truffle-dsl-processor-0.6.orig/0000755000000000000000000000000012460760144013454 5ustar truffle-dsl-processor-0.6.orig/com/0000755000000000000000000000000012460760144014232 5ustar truffle-dsl-processor-0.6.orig/com/oracle/0000755000000000000000000000000012460760144015477 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/0000755000000000000000000000000012460760144017146 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/0000755000000000000000000000000012460760144017730 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/0000755000000000000000000000000012460760144021747 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/0000755000000000000000000000000012460760144023243 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/CreateCastParser.java0000644000000000000000000001055312445312576027312 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; public class CreateCastParser extends NodeMethodParser { public CreateCastParser(ProcessorContext context, NodeData operation) { super(context, operation); } @Override public Class getAnnotationType() { return CreateCast.class; } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { List childNames = ElementUtils.getAnnotationValueList(String.class, mirror, "value"); NodeChildData foundChild = null; for (String childName : childNames) { foundChild = getNode().findChild(childName); if (foundChild != null) { break; } } TypeMirror baseType = getContext().getTruffleTypes().getNode(); if (foundChild != null) { baseType = foundChild.getOriginalType(); } MethodSpec spec = new MethodSpec(new InheritsParameterSpec("child", baseType)); addDefaultFieldMethodSpec(spec); ParameterSpec childSpec = new ParameterSpec("castedChild", baseType); childSpec.setSignature(true); spec.addRequired(childSpec); return spec; } @Override public CreateCastData create(TemplateMethod method, boolean invalid) { AnnotationMirror mirror = method.getMarkerAnnotation(); List childNames = ElementUtils.getAnnotationValueList(String.class, mirror, "value"); CreateCastData cast = new CreateCastData(method, childNames); AnnotationValue value = ElementUtils.getAnnotationValue(mirror, "value"); TypeMirror type = null; if (childNames == null || childNames.isEmpty()) { cast.addError(value, "No value specified but required."); return cast; } for (String childName : childNames) { NodeChildData child = getNode().findChild(childName); if (child == null) { // error cast.addError(value, "Specified child '%s' not found.", childName); continue; } if (type == null) { type = child.getNodeType(); } else if (!ElementUtils.typeEquals(type, child.getNodeType())) { cast.addError(value, "All child nodes for a cast must have the same node type."); continue; } } return cast; } private static class InheritsParameterSpec extends ParameterSpec { public InheritsParameterSpec(String name, TypeMirror... allowedTypes) { super(name, Arrays.asList(allowedTypes), null); } @Override public boolean matches(TypeMirror actualType) { boolean found = false; for (TypeMirror specType : getAllowedTypes()) { if (ElementUtils.isAssignable(actualType, specType)) { found = true; break; } } return found; } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/GenericParser.java0000644000000000000000000000544212445312576026651 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind; public class GenericParser extends NodeMethodParser { public GenericParser(ProcessorContext context, NodeData node) { super(context, node); } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { return createDefaultMethodSpec(method, mirror, true, null); } @Override protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) { List execTypes = execution.getChild().findGenericExecutableTypes(getContext()); List types = new ArrayList<>(); Set typeIds = new HashSet<>(); for (ExecutableTypeData type : execTypes) { TypeMirror typeMirror = type.getType().getPrimitiveType(); types.add(typeMirror); typeIds.add(ElementUtils.getUniqueIdentifier(typeMirror)); } ParameterSpec spec = new ParameterSpec(execution.getName(), types, typeIds); spec.setExecution(execution); return spec; } @Override public SpecializationData create(TemplateMethod method, boolean invalid) { return new SpecializationData(getNode(), method, SpecializationKind.GENERIC); } @Override public Class getAnnotationType() { return Fallback.class; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/TypeCastParser.java0000644000000000000000000000612412445312576027027 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import javax.lang.model.element.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; class TypeCastParser extends TypeSystemMethodParser { public TypeCastParser(ProcessorContext context, TypeSystemData typeSystem) { super(context, typeSystem); } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { TypeData targetType = findTypeByMethodName(method.getSimpleName().toString(), "as"); if (targetType == null) { return null; } MethodSpec spec = new MethodSpec(new ParameterSpec("returnType", targetType.getPrimitiveType())); spec.addRequired(new ParameterSpec("value", getTypeSystem().getPrimitiveTypeMirrors(), getTypeSystem().getTypeIdentifiers())); return spec; } @Override public TypeCastData create(TemplateMethod method, boolean invalid) { if (invalid) { return new TypeCastData(method, null, null); } TypeData targetType = findTypeByMethodName(method, "as"); Parameter parameter = method.findParameter("valueValue"); TypeData sourceType = null; if (parameter != null) { sourceType = getTypeSystem().findTypeData(parameter.getType()); } TypeCastData cast = new TypeCastData(method, sourceType, targetType); if (targetType != method.getReturnType().getTypeSystemType()) { cast.addError("Cast type %s does not match to the returned type %s.", ElementUtils.getSimpleName(targetType.getPrimitiveType()), method.getReturnType() != null ? ElementUtils.getSimpleName(method.getReturnType().getTypeSystemType().getPrimitiveType()) : null); } return cast; } @Override public Class getAnnotationType() { return TypeCast.class; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/GuardParser.java0000644000000000000000000001164012445312576026334 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; public class GuardParser extends NodeMethodParser { private final GuardExpression expression; private final TemplateMethod guardedMethod; public GuardParser(ProcessorContext context, NodeData node, TemplateMethod compatibleSource, GuardExpression expression) { super(context, node); this.expression = expression; this.guardedMethod = compatibleSource; getParser().setEmitErrors(false); setParseNullOnError(false); } @Override protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) { return super.createValueParameterSpec(execution); } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { MethodSpec spec = createDefaultMethodSpec(method, mirror, true, null); spec.setIgnoreAdditionalSpecifications(true); spec.getRequired().clear(); if (expression.getResolvedChildren() != null) { for (NodeExecutionData execution : expression.getResolvedChildren()) { List foundInGuardedMethod = guardedMethod.findByExecutionData(execution); for (Parameter guardedParameter : foundInGuardedMethod) { spec.addRequired(createParameterSpec(guardedParameter)); } } } else { for (Parameter parameter : guardedMethod.getRequiredParameters()) { spec.addRequired(createParameterSpec(parameter)); } } return spec; } private ParameterSpec createParameterSpec(Parameter parameter) { List typeMirrors = ElementUtils.getAssignableTypes(getContext(), parameter.getType()); Set typeIds = new HashSet<>(); for (TypeMirror typeMirror : typeMirrors) { typeIds.add(ElementUtils.getUniqueIdentifier(typeMirror)); } if (parameter.getSpecification().isSignature()) { typeIds.retainAll(getTypeSystem().getTypeIdentifiers()); } return new ParameterSpec(parameter.getSpecification(), typeMirrors, typeIds); } @Override protected List nodeTypeMirrors(NodeData nodeData) { Set typeMirrors = new LinkedHashSet<>(); typeMirrors.addAll(nodeData.getTypeSystem().getPrimitiveTypeMirrors()); typeMirrors.addAll(nodeData.getTypeSystem().getBoxedTypeMirrors()); return new ArrayList<>(typeMirrors); } @Override protected Set nodeTypeIdentifiers(NodeData nodeData) { return nodeData.getTypeSystem().getTypeIdentifiers(); } @Override protected ParameterSpec createReturnParameterSpec() { return new ParameterSpec("returnType", getContext().getType(boolean.class)); } @Override public boolean isParsable(ExecutableElement method) { return true; } @Override public GuardData create(TemplateMethod method, boolean invalid) { Implies impliesAnnotation = method.getMethod().getAnnotation(Implies.class); String[] impliesExpressions = new String[0]; if (impliesAnnotation != null) { impliesExpressions = impliesAnnotation.value(); } List guardExpressions = new ArrayList<>(); for (String string : impliesExpressions) { guardExpressions.add(new GuardExpression(string, false)); } return new GuardData(method, guardExpressions); } @Override public Class getAnnotationType() { return null; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/TypeSystemMethodParser.java0000644000000000000000000000553312445312576030565 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import javax.lang.model.element.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; abstract class TypeSystemMethodParser extends TemplateMethodParser { public TypeSystemMethodParser(ProcessorContext context, TypeSystemData typeSystem) { super(context, typeSystem); } @Override public final boolean isParsable(ExecutableElement method) { return ElementUtils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null; } protected TypeData findTypeByMethodName(String methodName, String prefix) { String typeName = methodName.substring(prefix.length(), methodName.length()); TypeData type = getTypeSystem().findType(typeName); return type; } protected TypeData findTypeByMethodName(TemplateMethod method, String prefix) { String methodName = method.getMethodName(); if (!methodName.startsWith(prefix)) { String annotationName = ElementUtils.getSimpleName(method.getMessageAnnotation().getAnnotationType()); method.addError("Methods annotated with %s must match the pattern '%s'.", annotationName, String.format("%s${typeName}", prefix)); return null; } String typeName = methodName.substring(prefix.length(), methodName.length()); TypeData type = getTypeSystem().findType(typeName); if (type == null) { String annotationName = TypeSystem.class.getSimpleName(); method.addError("Type '%s' is not declared in this @%s.", typeName, annotationName); return null; } return type; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/NodeMethodParser.java0000644000000000000000000001122612445312576027320 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; public abstract class NodeMethodParser extends TemplateMethodParser { public NodeMethodParser(ProcessorContext context, NodeData node) { super(context, node); } public NodeData getNode() { return template; } protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) { ParameterSpec spec = new ParameterSpec(execution.getName(), nodeTypeMirrors(execution.getChild().getNodeData()), nodeTypeIdentifiers(execution.getChild().getNodeData())); spec.setExecution(execution); return spec; } protected List nodeTypeMirrors(NodeData nodeData) { return nodeData.getTypeSystem().getPrimitiveTypeMirrors(); } protected Set nodeTypeIdentifiers(NodeData nodeData) { return nodeData.getTypeSystem().getTypeIdentifiers(); } protected ParameterSpec createReturnParameterSpec() { ParameterSpec returnValue = new ParameterSpec("returnValue", nodeTypeMirrors(getNode()), nodeTypeIdentifiers(getNode())); returnValue.setExecution(getNode().getThisExecution()); return returnValue; } @Override public boolean isParsable(ExecutableElement method) { if (getAnnotationType() != null) { return ElementUtils.findAnnotationMirror(getContext().getEnvironment(), method, getAnnotationType()) != null; } return true; } @SuppressWarnings("unused") protected final MethodSpec createDefaultMethodSpec(ExecutableElement method, AnnotationMirror mirror, boolean shortCircuitsEnabled, String shortCircuitName) { MethodSpec methodSpec = new MethodSpec(createReturnParameterSpec()); addDefaultFrame(methodSpec); addDefaultFieldMethodSpec(methodSpec); addDefaultChildren(shortCircuitsEnabled, shortCircuitName, methodSpec); return methodSpec; } private void addDefaultChildren(boolean shortCircuitsEnabled, String breakName, MethodSpec spec) { if (getNode().getChildren() == null) { // children are null when parsing executable types return; } for (NodeExecutionData execution : getNode().getChildExecutions()) { if (breakName != null && execution.getShortCircuitId().equals(breakName)) { break; } if (execution.isShortCircuit() && shortCircuitsEnabled) { spec.addRequired(new ParameterSpec(shortCircuitValueName(execution.getName()), getContext().getType(boolean.class))); } spec.addRequired(createValueParameterSpec(execution)); } } private void addDefaultFrame(MethodSpec methodSpec) { if (getNode().supportsFrame()) { methodSpec.addOptional(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame())); } } protected void addDefaultFieldMethodSpec(MethodSpec methodSpec) { for (NodeFieldData field : getNode().getFields()) { if (field.getGetter() == null) { ParameterSpec spec = new ParameterSpec(field.getName(), field.getType()); spec.setLocal(true); methodSpec.addOptional(spec); } } } private static String shortCircuitValueName(String valueName) { return "has" + ElementUtils.firstLetterUpperCase(valueName); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/AbstractParser.java0000644000000000000000000001321212445312576027032 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; import javax.tools.Diagnostic.Kind; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; import com.oracle.truffle.dsl.processor.model.MessageContainer.Message; /** * THIS IS NOT PUBLIC API. */ public abstract class AbstractParser { protected final ProcessorContext context; protected final ProcessingEnvironment processingEnv; protected final Log log; public AbstractParser() { this.context = ProcessorContext.getInstance(); this.processingEnv = context.getEnvironment(); this.log = context.getLog(); } public final M parse(Element element) { M model = null; try { AnnotationMirror mirror = null; if (getAnnotationType() != null) { mirror = ElementUtils.findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), getAnnotationType()); } if (!context.getTruffleTypes().verify(context, element, mirror)) { return null; } model = parse(element, mirror); if (model == null) { return null; } redirectMessages(new HashSet(), model, model); model.emitMessages(context, log); return filterErrorElements(model); } catch (CompileErrorException e) { log.message(Kind.WARNING, element, null, null, "The truffle processor could not parse class due to error: %s", e.getMessage()); return null; } } private void redirectMessages(Set visitedSinks, MessageContainer model, MessageContainer baseContainer) { List messages = model.getMessages(); for (int i = messages.size() - 1; i >= 0; i--) { Message message = messages.get(i); if (!ElementUtils.isEnclosedIn(baseContainer.getMessageElement(), message.getOriginalContainer().getMessageElement())) { // redirect message MessageContainer original = message.getOriginalContainer(); String text = wrapText(original.getMessageElement(), original.getMessageAnnotation(), message.getText()); Message redirectedMessage = new Message(null, null, baseContainer, text, message.getKind()); model.getMessages().remove(i); baseContainer.getMessages().add(redirectedMessage); } } for (MessageContainer childContainer : model) { if (visitedSinks.contains(childContainer)) { continue; } visitedSinks.add(childContainer); MessageContainer newBase = baseContainer; if (childContainer.getBaseContainer() != null) { newBase = childContainer.getBaseContainer(); } redirectMessages(visitedSinks, childContainer, newBase); } } private static String wrapText(Element element, AnnotationMirror mirror, String text) { StringBuilder b = new StringBuilder(); if (element != null) { if (element.getKind() == ElementKind.METHOD) { b.append("Method " + ElementUtils.createReferenceName((ExecutableElement) element)); } else { b.append("Element " + element.getSimpleName()); } } if (mirror != null) { b.append(" at annotation @" + ElementUtils.getSimpleName(mirror.getAnnotationType()).trim()); } if (b.length() > 0) { b.append(" is erroneous: ").append(text); return b.toString(); } else { return text; } } protected M filterErrorElements(M model) { return model.hasErrors() ? null : model; } protected abstract M parse(Element element, AnnotationMirror mirror); public abstract Class getAnnotationType(); public boolean isDelegateToRootDeclaredType() { return false; } public List> getAllAnnotationTypes() { List> list = new ArrayList<>(); if (getAnnotationType() != null) { list.add(getAnnotationType()); } list.addAll(getTypeDelegatedAnnotationTypes()); return list; } public List> getTypeDelegatedAnnotationTypes() { return Collections.emptyList(); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/ShortCircuitParser.java0000644000000000000000000000550612445312576027720 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; public class ShortCircuitParser extends NodeMethodParser { private final Set shortCircuitValues; public ShortCircuitParser(ProcessorContext context, NodeData node) { super(context, node); shortCircuitValues = new HashSet<>(); for (NodeExecutionData execution : node.getChildExecutions()) { if (execution.isShortCircuit()) { shortCircuitValues.add(execution.getShortCircuitId()); } } } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { String shortCircuitValue = ElementUtils.getAnnotationValue(String.class, mirror, "value"); return createDefaultMethodSpec(method, mirror, true, shortCircuitValue); } @Override protected ParameterSpec createReturnParameterSpec() { return new ParameterSpec("has", getContext().getType(boolean.class)); } @Override public ShortCircuitData create(TemplateMethod method, boolean invalid) { String shortCircuitValue = ElementUtils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "value"); if (!shortCircuitValues.contains(shortCircuitValue)) { method.addError("Invalid short circuit value %s.", shortCircuitValue); } return new ShortCircuitData(method, shortCircuitValue); } @Override public Class getAnnotationType() { return ShortCircuit.class; } } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/ExecutableTypeMethodParser.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/ExecutableTypeMethodParser.ja0000644000000000000000000000723312445312576031032 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.model.*; public class ExecutableTypeMethodParser extends NodeMethodParser { public ExecutableTypeMethodParser(ProcessorContext context, NodeData node) { super(context, node); setParseNullOnError(false); getParser().setEmitErrors(false); getParser().setUseVarArgs(true); } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { MethodSpec spec = createDefaultMethodSpec(method, mirror, false, null); List requiredSpecs = new ArrayList<>(spec.getRequired()); spec.getRequired().clear(); List allowedTypes = getNode().getTypeSystem().getPrimitiveTypeMirrors(); Set allowedIdentifiers = getNode().getTypeSystem().getTypeIdentifiers(); for (ParameterSpec originalSpec : requiredSpecs) { spec.addRequired(new ParameterSpec(originalSpec, allowedTypes, allowedIdentifiers)); } spec.setIgnoreAdditionalSpecifications(true); spec.setIgnoreAdditionalParameters(true); spec.setVariableRequiredParameters(true); // varargs ParameterSpec otherParameters = new ParameterSpec("other", allowedTypes, allowedIdentifiers); otherParameters.setSignature(true); spec.addRequired(otherParameters); return spec; } @Override protected List nodeTypeMirrors(NodeData nodeData) { return getNode().getTypeSystem().getPrimitiveTypeMirrors(); } @Override protected Set nodeTypeIdentifiers(NodeData nodeData) { return getNode().getTypeSystem().getTypeIdentifiers(); } @Override public final boolean isParsable(ExecutableElement method) { if (method.getModifiers().contains(Modifier.STATIC)) { return false; } else if (method.getModifiers().contains(Modifier.NATIVE)) { return false; } return method.getSimpleName().toString().startsWith("execute"); } @Override public ExecutableTypeData create(TemplateMethod method, boolean invalid) { TypeData resolvedType = method.getReturnType().getTypeSystemType(); return new ExecutableTypeData(method, method.getMethod(), getNode().getTypeSystem(), resolvedType); } @Override public Class getAnnotationType() { return null; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/ImplicitCastParser.java0000644000000000000000000000542312445312576027661 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.model.*; public class ImplicitCastParser extends TypeSystemMethodParser { public ImplicitCastParser(ProcessorContext context, TypeSystemData typeSystem) { super(context, typeSystem); } @Override public Class getAnnotationType() { return ImplicitCast.class; } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { List types = getTypeSystem().getPrimitiveTypeMirrors(); Set identifiers = getTypeSystem().getTypeIdentifiers(); MethodSpec spec = new MethodSpec(new ParameterSpec("target", types, identifiers)); spec.addRequired(new ParameterSpec("source", types, identifiers)); return spec; } @Override public ImplicitCastData create(TemplateMethod method, boolean invalid) { if (invalid) { return new ImplicitCastData(method, null, null); } Parameter target = method.findParameter("targetValue"); Parameter source = method.findParameter("sourceValue"); TypeData targetType = target.getTypeSystemType(); TypeData sourceType = source.getTypeSystemType(); if (targetType.equals(sourceType)) { method.addError("Target type and source type of an @%s must not be the same type.", ImplicitCast.class.getSimpleName()); } return new ImplicitCastData(method, sourceType, targetType); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/NodeParser.java0000644000000000000000000017200712445312576026164 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import javax.tools.Diagnostic.Kind; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.compiler.*; import com.oracle.truffle.dsl.processor.model.*; import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind; import com.oracle.truffle.dsl.processor.model.TemplateMethod.TypeSignature; public class NodeParser extends AbstractParser { public static final List> ANNOTATIONS = Arrays.asList(Fallback.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, NodeChild.class, NodeChildren.class); private Map parsedNodes; @Override protected NodeData parse(Element element, AnnotationMirror mirror) { NodeData node = null; try { parsedNodes = new HashMap<>(); node = resolveNode((TypeElement) element); if (Log.DEBUG) { NodeData parsed = parsedNodes.get(ElementUtils.getQualifiedName((TypeElement) element)); if (node != null) { String dump = parsed.dump(); log.message(Kind.ERROR, null, null, null, dump); } } } finally { parsedNodes = null; } return node; } @Override protected NodeData filterErrorElements(NodeData model) { for (Iterator iterator = model.getEnclosingNodes().iterator(); iterator.hasNext();) { NodeData node = filterErrorElements(iterator.next()); if (node == null) { iterator.remove(); } } if (model.hasErrors()) { return null; } return model; } @Override public boolean isDelegateToRootDeclaredType() { return true; } @Override public Class getAnnotationType() { return null; } @Override public List> getTypeDelegatedAnnotationTypes() { return ANNOTATIONS; } private NodeData resolveNode(TypeElement rootType) { String typeName = ElementUtils.getQualifiedName(rootType); if (parsedNodes.containsKey(typeName)) { return parsedNodes.get(typeName); } List enclosedNodes = new ArrayList<>(); for (TypeElement enclosedType : ElementFilter.typesIn(rootType.getEnclosedElements())) { NodeData enclosedChild = resolveNode(enclosedType); if (enclosedChild != null) { enclosedNodes.add(enclosedChild); } } NodeData node = parseNode(rootType); if (node == null && !enclosedNodes.isEmpty()) { node = new NodeData(context, rootType); } if (node != null) { for (NodeData enclosedNode : enclosedNodes) { node.addEnclosedNode(enclosedNode); } } parsedNodes.put(typeName, node); return node; } private NodeData parseNode(TypeElement originalTemplateType) { // reloading the type elements is needed for ecj TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType)); if (ElementUtils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) { // generated nodes should not get called again. return null; } List lookupTypes = collectSuperClasses(new ArrayList(), templateType); if (!ElementUtils.isAssignable(templateType.asType(), context.getTruffleTypes().getNode())) { return null; } List elements = new ArrayList<>(CompilerFactory.getCompiler(templateType).getAllMembersInDeclarationOrder(context.getEnvironment(), templateType)); NodeData node = parseNodeData(templateType, elements, lookupTypes); parseImportGuards(node, lookupTypes, elements); if (node.hasErrors()) { return node; // error sync point } node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node).parse(elements))); initializeChildren(node); node.getSpecializations().addAll(new SpecializationMethodParser(context, node).parse(elements)); node.getSpecializations().addAll(new GenericParser(context, node).parse(elements)); node.getCasts().addAll(new CreateCastParser(context, node).parse(elements)); node.getShortCircuits().addAll(new ShortCircuitParser(context, node).parse(elements)); if (node.hasErrors()) { return node; // error sync point } verifySpecializationSameLength(node); initializeSpecializations(elements, node); initializeShortCircuits(node); // requires specializations and polymorphic specializations verifyVisibilities(node); verifyMissingAbstractMethods(node, elements); verifyConstructors(node); verifyNamingConvention(node.getShortCircuits(), "needs"); verifySpecializationThrows(node); return node; } private void parseImportGuards(NodeData node, List lookupTypes, List elements) { for (TypeElement lookupType : lookupTypes) { AnnotationMirror importAnnotation = ElementUtils.findAnnotationMirror(processingEnv, lookupType, ImportGuards.class); if (importAnnotation == null) { continue; } AnnotationValue importClassesValue = ElementUtils.getAnnotationValue(importAnnotation, "value"); List importClasses = ElementUtils.getAnnotationValueList(TypeMirror.class, importAnnotation, "value"); if (importClasses.isEmpty()) { node.addError(importAnnotation, importClassesValue, "At least import guard classes must be specified."); continue; } for (TypeMirror importGuardClass : importClasses) { if (importGuardClass.getKind() != TypeKind.DECLARED) { node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' is not a declared type.", ElementUtils.getQualifiedName(importGuardClass)); continue; } TypeElement typeElement = ElementUtils.fromTypeMirror(importGuardClass); // hack to reload type is necessary for incremental compiling in eclipse. // otherwise methods inside of import guard types are just not found. typeElement = ElementUtils.fromTypeMirror(context.reloadType(typeElement.asType())); if (typeElement.getEnclosingElement().getKind().isClass() && !typeElement.getModifiers().contains(Modifier.PUBLIC)) { node.addError(importAnnotation, importClassesValue, "The specified import guard class '%s' must be public.", ElementUtils.getQualifiedName(importGuardClass)); continue; } List importMethods = ElementFilter.methodsIn(processingEnv.getElementUtils().getAllMembers(typeElement)); for (ExecutableElement importMethod : importMethods) { if (!importMethod.getModifiers().contains(Modifier.PUBLIC) || !importMethod.getModifiers().contains(Modifier.STATIC)) { continue; } elements.add(importMethod); } } } } private NodeData parseNodeData(TypeElement templateType, List elements, List typeHierarchy) { AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class); if (typeSystemMirror == null) { NodeData nodeData = new NodeData(context, templateType); nodeData.addError("No @%s annotation found in type hierarchy of %s.", TypeSystemReference.class.getSimpleName(), ElementUtils.getQualifiedName(templateType)); return nodeData; } TypeMirror typeSystemType = ElementUtils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value"); final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSystemType, true); if (typeSystem == null) { NodeData nodeData = new NodeData(context, templateType); nodeData.addError("The used type system '%s' is invalid or not a Node.", ElementUtils.getQualifiedName(typeSystemType)); return nodeData; } List assumptionsList = new ArrayList<>(); for (int i = typeHierarchy.size() - 1; i >= 0; i--) { TypeElement type = typeHierarchy.get(i); AnnotationMirror assumptions = ElementUtils.findAnnotationMirror(context.getEnvironment(), type, NodeAssumptions.class); if (assumptions != null) { List assumptionStrings = ElementUtils.getAnnotationValueList(String.class, assumptions, "value"); for (String string : assumptionStrings) { if (assumptionsList.contains(string)) { assumptionsList.remove(string); } assumptionsList.add(string); } } } AnnotationMirror nodeInfoMirror = findFirstAnnotation(typeHierarchy, NodeInfo.class); String shortName = null; if (nodeInfoMirror != null) { shortName = ElementUtils.getAnnotationValue(String.class, nodeInfoMirror, "shortName"); } List fields = parseFields(typeHierarchy, elements); List children = parseChildren(typeHierarchy, elements); List executions = parseExecutions(children, elements); NodeData nodeData = new NodeData(context, templateType, shortName, typeSystem, children, executions, fields, assumptionsList); parsedNodes.put(ElementUtils.getQualifiedName(templateType), nodeData); return nodeData; } private List parseFields(List typeHierarchy, List elements) { Set names = new HashSet<>(); List fields = new ArrayList<>(); for (VariableElement field : ElementFilter.fieldsIn(elements)) { if (field.getModifiers().contains(Modifier.STATIC)) { continue; } if (field.getModifiers().contains(Modifier.PUBLIC) || field.getModifiers().contains(Modifier.PROTECTED)) { String name = field.getSimpleName().toString(); fields.add(new NodeFieldData(field, null, field.asType(), name, false)); names.add(name); } } List reversedTypeHierarchy = new ArrayList<>(typeHierarchy); Collections.reverse(reversedTypeHierarchy); for (TypeElement typeElement : reversedTypeHierarchy) { AnnotationMirror nodeChildrenMirror = ElementUtils.findAnnotationMirror(processingEnv, typeElement, NodeFields.class); List children = ElementUtils.collectAnnotations(context, nodeChildrenMirror, "value", typeElement, NodeField.class); for (AnnotationMirror mirror : children) { String name = ElementUtils.firstLetterLowerCase(ElementUtils.getAnnotationValue(String.class, mirror, "name")); TypeMirror type = ElementUtils.getAnnotationValue(TypeMirror.class, mirror, "type"); NodeFieldData field = new NodeFieldData(typeElement, mirror, type, name, true); if (name.isEmpty()) { field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Field name cannot be empty."); } else if (names.contains(name)) { field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Duplicate field name '%s'.", name); } names.add(name); fields.add(field); } } for (NodeFieldData nodeFieldData : fields) { nodeFieldData.setGetter(findGetter(elements, nodeFieldData.getName(), nodeFieldData.getType())); } return fields; } private List parseChildren(final List typeHierarchy, List elements) { Set shortCircuits = new HashSet<>(); for (ExecutableElement method : ElementFilter.methodsIn(elements)) { AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, ShortCircuit.class); if (mirror != null) { shortCircuits.add(ElementUtils.getAnnotationValue(String.class, mirror, "value")); } } Map castNodeTypes = new HashMap<>(); for (ExecutableElement method : ElementFilter.methodsIn(elements)) { AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, CreateCast.class); if (mirror != null) { List children = (ElementUtils.getAnnotationValueList(String.class, mirror, "value")); if (children != null) { for (String child : children) { castNodeTypes.put(child, method.getReturnType()); } } } } List parsedChildren = new ArrayList<>(); List typeHierarchyReversed = new ArrayList<>(typeHierarchy); Collections.reverse(typeHierarchyReversed); for (TypeElement type : typeHierarchyReversed) { AnnotationMirror nodeChildrenMirror = ElementUtils.findAnnotationMirror(processingEnv, type, NodeChildren.class); TypeMirror nodeClassType = type.getSuperclass(); if (!ElementUtils.isAssignable(nodeClassType, context.getTruffleTypes().getNode())) { nodeClassType = null; } List children = ElementUtils.collectAnnotations(context, nodeChildrenMirror, "value", type, NodeChild.class); int index = 0; for (AnnotationMirror childMirror : children) { String name = ElementUtils.getAnnotationValue(String.class, childMirror, "value"); if (name.equals("")) { name = "child" + index; } Cardinality cardinality = Cardinality.ONE; TypeMirror childType = inheritType(childMirror, "type", nodeClassType); if (childType.getKind() == TypeKind.ARRAY) { cardinality = Cardinality.MANY; } TypeMirror originalChildType = childType; TypeMirror castNodeType = castNodeTypes.get(name); if (castNodeType != null) { childType = castNodeType; } Element getter = findGetter(elements, name, childType); NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childType, originalChildType, getter, cardinality); parsedChildren.add(nodeChild); if (nodeChild.getNodeType() == null) { nodeChild.addError("No valid node type could be resoleved."); } if (nodeChild.hasErrors()) { continue; } index++; } } List filteredChildren = new ArrayList<>(); Set encounteredNames = new HashSet<>(); for (int i = parsedChildren.size() - 1; i >= 0; i--) { NodeChildData child = parsedChildren.get(i); if (!encounteredNames.contains(child.getName())) { filteredChildren.add(0, child); encounteredNames.add(child.getName()); } } for (NodeChildData child : filteredChildren) { List executeWithStrings = ElementUtils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith"); AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith"); List executeWith = new ArrayList<>(); for (String executeWithString : executeWithStrings) { if (child.getName().equals(executeWithString)) { child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString); continue; } NodeChildData found = null; boolean before = true; for (NodeChildData resolveChild : filteredChildren) { if (resolveChild == child) { before = false; continue; } if (resolveChild.getName().equals(executeWithString)) { found = resolveChild; break; } } if (found == null) { child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString); continue; } else if (!before) { child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString, executeWithString); continue; } executeWith.add(found); } child.setExecuteWith(executeWith); if (child.getNodeData() == null) { continue; } } return filteredChildren; } private List parseExecutions(List children, List elements) { if (children == null) { return null; } // pre-parse short circuits Set shortCircuits = new HashSet<>(); List methods = ElementFilter.methodsIn(elements); for (ExecutableElement method : methods) { AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, ShortCircuit.class); if (mirror != null) { shortCircuits.add(ElementUtils.getAnnotationValue(String.class, mirror, "value")); } } boolean hasVarArgs = false; int maxSignatureSize = 0; if (!children.isEmpty()) { int lastIndex = children.size() - 1; hasVarArgs = children.get(lastIndex).getCardinality() == Cardinality.MANY; if (hasVarArgs) { maxSignatureSize = lastIndex; } else { maxSignatureSize = children.size(); } } // pre-parse specializations for (ExecutableElement method : methods) { AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, Specialization.class); if (mirror == null) { continue; } int currentArgumentCount = 0; boolean skipShortCircuit = false; for (VariableElement var : method.getParameters()) { TypeMirror type = var.asType(); if (currentArgumentCount == 0) { // skip optionals if (ElementUtils.typeEquals(type, context.getTruffleTypes().getFrame())) { continue; } // TODO skip optional fields? } int childIndex = currentArgumentCount < children.size() ? currentArgumentCount : children.size() - 1; if (childIndex == -1) { continue; } if (!skipShortCircuit) { NodeChildData child = children.get(childIndex); if (shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, currentArgumentCount - childIndex))) { skipShortCircuit = true; continue; } } else { skipShortCircuit = false; } currentArgumentCount++; } maxSignatureSize = Math.max(maxSignatureSize, currentArgumentCount); } List executions = new ArrayList<>(); for (int i = 0; i < maxSignatureSize; i++) { int childIndex = i; boolean varArg = false; if (childIndex >= children.size() - 1) { if (hasVarArgs) { childIndex = children.size() - 1; varArg = hasVarArgs; } else if (childIndex >= children.size()) { break; } } int varArgsIndex = varArg ? Math.abs(childIndex - i) : -1; NodeChildData child = children.get(childIndex); boolean shortCircuit = shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, varArgsIndex)); executions.add(new NodeExecutionData(child, varArgsIndex, shortCircuit)); } return executions; } private static Map> groupExecutableTypes(List executableTypes) { Map> groupedTypes = new TreeMap<>(); for (ExecutableTypeData type : executableTypes) { int evaluatedCount = type.getEvaluatedCount(); List types = groupedTypes.get(evaluatedCount); if (types == null) { types = new ArrayList<>(); groupedTypes.put(evaluatedCount, types); } types.add(type); } for (List types : groupedTypes.values()) { Collections.sort(types); } return groupedTypes; } private void initializeChildren(NodeData node) { for (NodeChildData nodeChild : node.getChildren()) { NodeData fieldNodeData = resolveNode(ElementUtils.fromTypeMirror(nodeChild.getNodeType())); nodeChild.setNode(fieldNodeData); if (fieldNodeData == null) { nodeChild.addError("Node type '%s' is invalid or not a valid Node.", ElementUtils.getQualifiedName(nodeChild.getNodeType())); } else if (!ElementUtils.typeEquals(fieldNodeData.getTypeSystem().getTemplateType().asType(), (node.getTypeSystem().getTemplateType().asType()))) { nodeChild.addError("The @%s of the node and the @%s of the @%s does not match. %s != %s. ", TypeSystem.class.getSimpleName(), TypeSystem.class.getSimpleName(), NodeChild.class.getSimpleName(), ElementUtils.getSimpleName(node.getTypeSystem().getTemplateType()), ElementUtils.getSimpleName(fieldNodeData.getTypeSystem().getTemplateType())); } if (fieldNodeData != null) { List types = nodeChild.findGenericExecutableTypes(context); if (types.isEmpty()) { AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(nodeChild.getMessageAnnotation(), "executeWith"); nodeChild.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s.", nodeChild.getExecuteWith().size(), ElementUtils.getSimpleName(nodeChild.getNodeType())); } } } } private void initializeSpecializations(List elements, final NodeData node) { if (node.getSpecializations().isEmpty()) { return; } initializeGuards(elements, node); initializeGeneric(node); initializeUninitialized(node); initializeOrder(node); initializePolymorphism(node); // requires specializations initializeReachability(node); initializeContains(node); if (!node.hasErrors()) { initializeExceptions(node); } resolveContains(node); List needsId = new ArrayList<>(); for (SpecializationData specialization : node.getSpecializations()) { if (specialization.isGeneric()) { specialization.setId("Generic"); } else if (specialization.isUninitialized()) { specialization.setId("Uninitialized"); } else if (specialization.isPolymorphic()) { specialization.setId("Polymorphic"); } else if (specialization.isSpecialized()) { needsId.add(specialization); } else { throw new AssertionError(); } } // verify specialization parameter length List ids = initializeSpecializationIds(needsId); for (int i = 0; i < ids.size(); i++) { needsId.get(i).setId(ids.get(i)); } } private static void initializeOrder(NodeData node) { List specializations = node.getSpecializations(); Collections.sort(specializations); for (SpecializationData specialization : specializations) { String searchName = specialization.getInsertBeforeName(); if (searchName == null || specialization.getMethod() == null) { continue; } SpecializationData found = lookupSpecialization(node, searchName); if (found == null || found.getMethod() == null) { AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "insertBefore"); specialization.addError(value, "The referenced specialization '%s' could not be found.", searchName); continue; } ExecutableElement currentMethod = specialization.getMethod(); ExecutableElement insertBeforeMethod = found.getMethod(); TypeMirror currentEnclosedType = currentMethod.getEnclosingElement().asType(); TypeMirror insertBeforeEnclosedType = insertBeforeMethod.getEnclosingElement().asType(); if (ElementUtils.typeEquals(currentEnclosedType, insertBeforeEnclosedType) || !ElementUtils.isSubtype(currentEnclosedType, insertBeforeEnclosedType)) { AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "insertBefore"); specialization.addError(value, "Specializations can only be inserted before specializations in superclasses.", searchName); continue; } specialization.setInsertBefore(found); } for (int i = 0; i < specializations.size(); i++) { SpecializationData specialization = specializations.get(i); SpecializationData insertBefore = specialization.getInsertBefore(); if (insertBefore != null) { int insertIndex = specializations.indexOf(insertBefore); if (insertIndex < i) { specializations.remove(i); specializations.add(insertIndex, specialization); } } } for (int i = 0; i < specializations.size(); i++) { specializations.get(i).setIndex(i); } } private static void initializeExceptions(NodeData node) { List specializations = node.getSpecializations(); for (int i = 0; i < specializations.size(); i++) { SpecializationData cur = specializations.get(i); if (cur.getExceptions().isEmpty()) { continue; } SpecializationData next = i + 1 < specializations.size() ? specializations.get(i + 1) : null; if (!cur.isContainedBy(next)) { next.addError("This specialiation is not a valid exceptional rewrite target for %s. To fix this make %s compatible to %s or remove the exceptional rewrite.", cur.createReferenceName(), next != null ? next.createReferenceName() : "-", cur.createReferenceName()); continue; } Set nextContains = next != null ? next.getContains() : Collections. emptySet(); if (!nextContains.contains(cur)) { nextContains.add(cur); } } for (SpecializationData cur : specializations) { if (cur.getExceptions().isEmpty()) { continue; } for (SpecializationData child : specializations) { if (child != null && child != cur && child.getContains().contains(cur)) { cur.getExcludedBy().add(child); } } } } private static void initializeContains(NodeData node) { for (SpecializationData specialization : node.getSpecializations()) { Set resolvedSpecializations = specialization.getContains(); resolvedSpecializations.clear(); Set includeNames = specialization.getContainsNames(); for (String includeName : includeNames) { // TODO reduce complexity of this lookup. SpecializationData foundSpecialization = lookupSpecialization(node, includeName); if (foundSpecialization == null) { AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "contains"); specialization.addError(value, "The referenced specialization '%s' could not be found.", includeName); } else { if (!foundSpecialization.isContainedBy(specialization)) { AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "contains"); if (foundSpecialization.compareTo(specialization) > 0) { specialization.addError(value, "The contained specialization '%s' must be declared before the containing specialization.", includeName); } else { specialization.addError(value, "The contained specialization '%s' is not fully compatible. The contained specialization must be strictly more generic than the containing one.", includeName); } } resolvedSpecializations.add(foundSpecialization); } } } } private void resolveContains(NodeData node) { // flatten transitive includes for (SpecializationData specialization : node.getSpecializations()) { if (specialization.getContains().isEmpty()) { continue; } Set foundSpecializations = new HashSet<>(); collectIncludes(specialization, foundSpecializations, new HashSet()); specialization.getContains().addAll(foundSpecializations); } } private static SpecializationData lookupSpecialization(NodeData node, String includeName) { SpecializationData foundSpecialization = null; for (SpecializationData searchSpecialization : node.getSpecializations()) { if (searchSpecialization.getMethodName().equals(includeName)) { foundSpecialization = searchSpecialization; break; } } return foundSpecialization; } private void collectIncludes(SpecializationData specialization, Set found, Set visited) { if (visited.contains(specialization)) { // circle found specialization.addError("Circular contained specialization '%s' found.", specialization.createReferenceName()); return; } visited.add(specialization); for (SpecializationData included : specialization.getContains()) { collectIncludes(included, found, new HashSet<>(visited)); found.add(included); } } private static void initializeReachability(final NodeData node) { List specializations = node.getSpecializations(); for (int i = specializations.size() - 1; i >= 0; i--) { SpecializationData current = specializations.get(i); if (current.isPolymorphic()) { current.setReachable(true); continue; } List shadowedBy = null; for (int j = i - 1; j >= 0; j--) { SpecializationData prev = specializations.get(j); if (prev.isPolymorphic()) { continue; } if (!current.isReachableAfter(prev)) { if (shadowedBy == null) { shadowedBy = new ArrayList<>(); } shadowedBy.add(prev); } } if (shadowedBy != null) { StringBuilder name = new StringBuilder(); String sep = ""; for (SpecializationData shadowSpecialization : shadowedBy) { name.append(sep); name.append(shadowSpecialization.createReferenceName()); sep = ", "; } current.addError("%s is not reachable. It is shadowed by %s.", current.isGeneric() ? "Generic" : "Specialization", name); } current.setReachable(shadowedBy == null); } } private static List initializeSpecializationIds(List specializations) { int lastSize = -1; List> signatureChunks = new ArrayList<>(); for (SpecializationData other : specializations) { if (!other.isSpecialized()) { continue; } List paramIds = new LinkedList<>(); paramIds.add(ElementUtils.getTypeId(other.getReturnType().getType())); for (Parameter param : other.getParameters()) { if (param.getSpecification().getExecution() == null) { continue; } paramIds.add(ElementUtils.getTypeId(param.getType())); } assert lastSize == -1 || lastSize == paramIds.size(); if (lastSize != -1 && lastSize != paramIds.size()) { throw new AssertionError(); } signatureChunks.add(paramIds); lastSize = paramIds.size(); } // reduce id vertically for (int i = 0; i < lastSize; i++) { String prev = null; boolean allSame = true; for (List signature : signatureChunks) { String arg = signature.get(i); if (prev == null) { prev = arg; continue; } else if (!prev.equals(arg)) { allSame = false; break; } prev = arg; } if (allSame) { for (List signature : signatureChunks) { signature.remove(i); } lastSize--; } } // reduce id horizontally for (List signature : signatureChunks) { if (signature.isEmpty()) { continue; } String prev = null; boolean allSame = true; for (String arg : signature) { if (prev == null) { prev = arg; continue; } else if (!prev.equals(arg)) { allSame = false; break; } prev = arg; } if (allSame) { signature.clear(); signature.add(prev); } } // create signatures List signatures = new ArrayList<>(); for (List signatureChunk : signatureChunks) { StringBuilder b = new StringBuilder(); if (signatureChunk.isEmpty()) { b.append("Default"); } else { for (String s : signatureChunk) { b.append(s); } } signatures.add(b.toString()); } Map counts = new HashMap<>(); for (String s1 : signatures) { Integer count = counts.get(s1); if (count == null) { count = 0; } count++; counts.put(s1, count); } for (String s : counts.keySet()) { int count = counts.get(s); if (count > 1) { int number = 0; for (ListIterator iterator = signatures.listIterator(); iterator.hasNext();) { String s2 = iterator.next(); if (s.equals(s2)) { iterator.set(s2 + number); number++; } } } } return signatures; } private void initializeGuards(List elements, NodeData node) { Map> potentialGuards = new HashMap<>(); for (SpecializationData specialization : node.getSpecializations()) { for (GuardExpression exp : specialization.getGuards()) { potentialGuards.put(exp.getGuardName(), null); } } TypeMirror booleanType = context.getType(boolean.class); for (ExecutableElement potentialGuard : ElementFilter.methodsIn(elements)) { if (potentialGuard.getModifiers().contains(Modifier.PRIVATE)) { continue; } String methodName = potentialGuard.getSimpleName().toString(); if (!potentialGuards.containsKey(methodName)) { continue; } if (!ElementUtils.typeEquals(potentialGuard.getReturnType(), booleanType)) { continue; } List potentialMethods = potentialGuards.get(methodName); if (potentialMethods == null) { potentialMethods = new ArrayList<>(); potentialGuards.put(methodName, potentialMethods); } potentialMethods.add(potentialGuard); } for (SpecializationData specialization : node.getSpecializations()) { for (GuardExpression exp : specialization.getGuards()) { resolveGuardExpression(node, specialization, potentialGuards, exp); } } } private void resolveGuardExpression(NodeData node, TemplateMethod source, Map> guards, GuardExpression expression) { List availableGuards = guards.get(expression.getGuardName()); if (availableGuards == null) { source.addError("No compatible guard with method name '%s' found.", expression.getGuardName()); return; } String[] childNames = expression.getChildNames(); if (childNames != null) { NodeExecutionData[] resolvedExecutions = new NodeExecutionData[childNames.length]; for (int i = 0; i < childNames.length; i++) { String childName = childNames[i]; NodeExecutionData execution = node.findExecutionByExpression(childName); if (execution == null) { source.addError("Guard parameter '%s' for guard '%s' could not be mapped to a declared child node.", childName, expression.getGuardName()); return; } resolvedExecutions[i] = execution; } expression.setResolvedChildren(resolvedExecutions); } GuardParser parser = new GuardParser(context, node, source, expression); List matchingGuards = parser.parse(availableGuards); if (!matchingGuards.isEmpty() && matchingGuards.get(0) != null) { expression.setResolvedGuard(matchingGuards.get(0)); } else { MethodSpec spec = parser.createSpecification(source.getMethod(), source.getMarkerAnnotation()); spec.applyTypeDefinitions("types"); source.addError("No guard with name '%s' matched the required signature. Expected signature: %n%s", expression.getGuardName(), spec.toSignatureString("guard")); } } private void initializeGeneric(final NodeData node) { if (!node.needsRewrites(context)) { return; } List generics = new ArrayList<>(); for (SpecializationData spec : node.getSpecializations()) { if (spec.isGeneric()) { generics.add(spec); } } if (generics.size() == 1 && node.getSpecializations().size() == 1) { // TODO this limitation should be lifted for (SpecializationData generic : generics) { generic.addError("@%s defined but no @%s.", Fallback.class.getSimpleName(), Specialization.class.getSimpleName()); } } if (generics.isEmpty()) { node.getSpecializations().add(createGenericSpecialization(node)); } else { if (generics.size() > 1) { for (SpecializationData generic : generics) { generic.addError("Only one @%s is allowed per operation.", Fallback.class.getSimpleName()); } } } } private SpecializationData createGenericSpecialization(final NodeData node) { GenericParser parser = new GenericParser(context, node); MethodSpec specification = parser.createDefaultMethodSpec(node.getSpecializations().iterator().next().getMethod(), null, true, null); List parameterTypes = new ArrayList<>(); int signatureIndex = 1; for (ParameterSpec spec : specification.getRequired()) { parameterTypes.add(createGenericType(spec, node.getSpecializations(), signatureIndex)); if (spec.isSignature()) { signatureIndex++; } } TypeMirror returnType = createGenericType(specification.getReturnType(), node.getSpecializations(), 0); SpecializationData generic = parser.create("Generic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, parameterTypes); if (generic == null) { throw new RuntimeException("Unable to create generic signature for node " + node.getNodeId() + " with " + parameterTypes + ". Specification " + specification + "."); } return generic; } private TypeMirror createGenericType(ParameterSpec spec, List specializations, int signatureIndex) { NodeExecutionData execution = spec.getExecution(); if (execution == null) { if (spec.getAllowedTypes().size() == 1) { return spec.getAllowedTypes().get(0); } else { return ElementUtils.getCommonSuperType(context, spec.getAllowedTypes().toArray(new TypeMirror[0])); } } else { Set types = new HashSet<>(); for (SpecializationData specialization : specializations) { types.add(specialization.getTypeSignature().get(signatureIndex)); } NodeChildData child = execution.getChild(); TypeData genericType = null; if (types.size() == 1) { ExecutableTypeData executable = child.findExecutableType(context, types.iterator().next()); if (executable != null && (signatureIndex == 0 || !executable.hasUnexpectedValue(context))) { genericType = types.iterator().next(); } } if (genericType == null) { genericType = child.findAnyGenericExecutableType(context).getType(); } return genericType.getPrimitiveType(); } } private static void initializeUninitialized(final NodeData node) { SpecializationData generic = node.getGenericSpecialization(); if (generic == null) { return; } for (Parameter parameter : generic.getReturnTypeAndParameters()) { if (ElementUtils.isObject(parameter.getType())) { continue; } Set types = new HashSet<>(); for (SpecializationData specialization : node.getSpecializations()) { Parameter actualParameter = specialization.findParameter(parameter.getLocalName()); if (actualParameter != null) { types.add(ElementUtils.getQualifiedName(actualParameter.getType())); } } if (types.size() > 1) { generic.replaceParameter(parameter.getLocalName(), new Parameter(parameter, node.getTypeSystem().getGenericTypeData())); } } TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", -1, node, generic.getSpecification(), null, null, generic.getReturnType(), generic.getParameters()); // should not use messages from generic specialization uninializedMethod.getMessages().clear(); node.getSpecializations().add(new SpecializationData(node, uninializedMethod, SpecializationKind.UNINITIALIZED)); } private void initializePolymorphism(NodeData node) { if (!node.needsRewrites(context)) { return; } SpecializationData generic = node.getGenericSpecialization(); List polymorphicSignature = new ArrayList<>(); List updatePolymorphic = Arrays.asList(); for (Parameter genericParameter : updatePolymorphic) { if (!genericParameter.getSpecification().isSignature()) { continue; } Set usedTypes = new HashSet<>(); for (SpecializationData specialization : node.getSpecializations()) { if (!specialization.isSpecialized()) { continue; } Parameter parameter = specialization.findParameter(genericParameter.getLocalName()); if (parameter == null) { throw new AssertionError("Parameter existed in generic specialization but not in specialized. param = " + genericParameter.getLocalName()); } usedTypes.add(parameter.getTypeSystemType()); } TypeData polymorphicType; if (usedTypes.size() == 1) { polymorphicType = usedTypes.iterator().next(); } else { polymorphicType = node.getTypeSystem().getGenericTypeData(); } polymorphicSignature.add(polymorphicType); } SpecializationData polymorphic = new SpecializationData(node, generic, SpecializationKind.POLYMORPHIC); polymorphic.updateSignature(new TypeSignature(polymorphicSignature)); node.getSpecializations().add(polymorphic); } private void initializeShortCircuits(NodeData node) { Map> groupedShortCircuits = groupShortCircuits(node.getShortCircuits()); boolean valid = true; List shortCircuitExecutions = new ArrayList<>(); for (NodeExecutionData execution : node.getChildExecutions()) { if (!execution.isShortCircuit()) { continue; } shortCircuitExecutions.add(execution); String valueName = execution.getShortCircuitId(); List availableCircuits = groupedShortCircuits.get(valueName); if (availableCircuits == null || availableCircuits.isEmpty()) { node.addError("@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName); valid = false; continue; } boolean sameMethodName = true; String methodName = availableCircuits.get(0).getMethodName(); for (ShortCircuitData circuit : availableCircuits) { if (!circuit.getMethodName().equals(methodName)) { sameMethodName = false; } } if (!sameMethodName) { for (ShortCircuitData circuit : availableCircuits) { circuit.addError("All short circuits for short cut value '%s' must have the same method name.", valueName); } valid = false; continue; } ShortCircuitData genericCircuit = null; for (ShortCircuitData circuit : availableCircuits) { if (isGenericShortCutMethod(circuit)) { genericCircuit = circuit; break; } } if (genericCircuit == null) { node.addError("No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName); valid = false; continue; } for (ShortCircuitData circuit : availableCircuits) { if (circuit != genericCircuit) { circuit.setGenericShortCircuitMethod(genericCircuit); } } } if (!valid) { return; } List specializations = new ArrayList<>(); specializations.addAll(node.getSpecializations()); for (SpecializationData specialization : specializations) { List assignedShortCuts = new ArrayList<>(shortCircuitExecutions.size()); for (NodeExecutionData shortCircuit : shortCircuitExecutions) { List availableShortCuts = groupedShortCircuits.get(shortCircuit.getShortCircuitId()); ShortCircuitData genericShortCircuit = null; ShortCircuitData compatibleShortCircuit = null; for (ShortCircuitData circuit : availableShortCuts) { if (circuit.isGeneric()) { genericShortCircuit = circuit; } else if (circuit.isCompatibleTo(specialization)) { compatibleShortCircuit = circuit; } } if (compatibleShortCircuit == null) { compatibleShortCircuit = genericShortCircuit; } assignedShortCuts.add(compatibleShortCircuit); } specialization.setShortCircuits(assignedShortCuts); } } private boolean isGenericShortCutMethod(ShortCircuitData method) { for (Parameter parameter : method.getParameters()) { NodeExecutionData execution = parameter.getSpecification().getExecution(); if (execution == null) { continue; } ExecutableTypeData found = null; List executableElements = execution.getChild().findGenericExecutableTypes(context); for (ExecutableTypeData executable : executableElements) { if (executable.getType().equalsType(parameter.getTypeSystemType())) { found = executable; break; } } if (found == null) { return false; } } return true; } private static Map> groupShortCircuits(List shortCircuits) { Map> group = new HashMap<>(); for (ShortCircuitData shortCircuit : shortCircuits) { List circuits = group.get(shortCircuit.getValueName()); if (circuits == null) { circuits = new ArrayList<>(); group.put(shortCircuit.getValueName(), circuits); } circuits.add(shortCircuit); } return group; } private static boolean verifySpecializationSameLength(NodeData nodeData) { int lastArgs = -1; for (SpecializationData specializationData : nodeData.getSpecializations()) { int signatureArgs = specializationData.getSignatureSize(); if (lastArgs == signatureArgs) { continue; } if (lastArgs != -1) { for (SpecializationData specialization : nodeData.getSpecializations()) { specialization.addError("All specializations must have the same number of arguments."); } return false; } else { lastArgs = signatureArgs; } } return true; } private static void verifyVisibilities(NodeData node) { if (node.getTemplateType().getModifiers().contains(Modifier.PRIVATE) && node.getSpecializations().size() > 0) { node.addError("Classes containing a @%s annotation must not be private.", Specialization.class.getSimpleName()); } } private static void verifyMissingAbstractMethods(NodeData nodeData, List originalElements) { if (!nodeData.needsFactory()) { // missing abstract methods only needs to be implemented // if we need go generate factory for it. return; } List elements = new ArrayList<>(originalElements); Set unusedElements = new HashSet<>(elements); for (TemplateMethod method : nodeData.getAllTemplateMethods()) { unusedElements.remove(method.getMethod()); } for (NodeFieldData field : nodeData.getFields()) { if (field.getGetter() != null) { unusedElements.remove(field.getGetter()); } } for (NodeChildData child : nodeData.getChildren()) { if (child.getAccessElement() != null) { unusedElements.remove(child.getAccessElement()); } } for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) { if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) { nodeData.addError("The type %s must implement the inherited abstract method %s.", ElementUtils.getSimpleName(nodeData.getTemplateType()), ElementUtils.getReadableSignature(unusedMethod)); } } } private static void verifyNamingConvention(List methods, String prefix) { for (int i = 0; i < methods.size(); i++) { TemplateMethod m1 = methods.get(i); if (m1.getMethodName().length() < 3 || !m1.getMethodName().startsWith(prefix)) { m1.addError("Naming convention: method name must start with '%s'.", prefix); } } } private static void verifySpecializationThrows(NodeData node) { Map specializationMap = new HashMap<>(); for (SpecializationData spec : node.getSpecializations()) { specializationMap.put(spec.getMethodName(), spec); } for (SpecializationData sourceSpecialization : node.getSpecializations()) { if (sourceSpecialization.getExceptions() != null) { for (SpecializationThrowsData throwsData : sourceSpecialization.getExceptions()) { for (SpecializationThrowsData otherThrowsData : sourceSpecialization.getExceptions()) { if (otherThrowsData != throwsData && ElementUtils.typeEquals(otherThrowsData.getJavaClass(), throwsData.getJavaClass())) { throwsData.addError("Duplicate exception type."); } } } } } } private void verifyConstructors(NodeData nodeData) { if (!nodeData.needsRewrites(context)) { // no specialization constructor is needed if the node never rewrites. return; } TypeElement type = ElementUtils.fromTypeMirror(nodeData.getNodeType()); List constructors = ElementFilter.constructorsIn(type.getEnclosedElements()); boolean parametersFound = false; for (ExecutableElement constructor : constructors) { if (!constructor.getParameters().isEmpty() && !isSourceSectionConstructor(context, constructor)) { parametersFound = true; } } if (!parametersFound) { return; } for (ExecutableElement e : constructors) { if (e.getParameters().size() == 1) { TypeMirror firstArg = e.getParameters().get(0).asType(); if (ElementUtils.typeEquals(firstArg, nodeData.getNodeType())) { if (e.getModifiers().contains(Modifier.PRIVATE)) { nodeData.addError("The specialization constructor must not be private."); } else if (constructors.size() <= 1) { nodeData.addError("The specialization constructor must not be the only constructor. The definition of an alternative constructor is required."); } return; } } } // not found nodeData.addError("Specialization constructor '%s(%s previousNode) { this(...); }' is required.", ElementUtils.getSimpleName(type), ElementUtils.getSimpleName(type)); } public static boolean isSourceSectionConstructor(ProcessorContext context, ExecutableElement constructor) { return constructor.getParameters().size() == 1 && ElementUtils.typeEquals(constructor.getParameters().get(0).asType(), context.getTruffleTypes().getSourceSection()); } private AnnotationMirror findFirstAnnotation(List elements, Class annotation) { for (Element element : elements) { AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, element, annotation); if (mirror != null) { return mirror; } } return null; } private TypeMirror inheritType(AnnotationMirror annotation, String valueName, TypeMirror parentType) { TypeMirror inhertNodeType = context.getTruffleTypes().getNode(); TypeMirror value = ElementUtils.getAnnotationValue(TypeMirror.class, annotation, valueName); if (ElementUtils.typeEquals(inhertNodeType, value)) { return parentType; } else { return value; } } private ExecutableElement findGetter(List elements, String variableName, TypeMirror type) { if (type == null) { return null; } String methodName; if (ElementUtils.typeEquals(type, context.getType(boolean.class))) { methodName = "is" + ElementUtils.firstLetterUpperCase(variableName); } else { methodName = "get" + ElementUtils.firstLetterUpperCase(variableName); } for (ExecutableElement method : ElementFilter.methodsIn(elements)) { if (method.getSimpleName().toString().equals(methodName) && method.getParameters().size() == 0 && ElementUtils.isAssignable(type, method.getReturnType())) { return method; } } return null; } private static List collectSuperClasses(List collection, TypeElement element) { if (element != null) { collection.add(element); if (element.getSuperclass() != null) { collectSuperClasses(collection, ElementUtils.fromTypeMirror(element.getSuperclass())); } } return collection; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/TypeSystemParser.java0000644000000000000000000003346312445312576027427 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.generator.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; public class TypeSystemParser extends AbstractParser { public static final List> ANNOTATIONS = Arrays.asList(TypeSystem.class, ExpectError.class); @Override public Class getAnnotationType() { return TypeSystem.class; } @Override protected TypeSystemData parse(Element element, AnnotationMirror mirror) { TypeElement templateType = (TypeElement) element; AnnotationMirror templateTypeAnnotation = mirror; TypeSystemData typeSystem = new TypeSystemData(context, templateType, templateTypeAnnotation); // annotation type on class path!? TypeElement annotationTypeElement = processingEnv.getElementUtils().getTypeElement(getAnnotationType().getCanonicalName()); if (annotationTypeElement == null) { typeSystem.addError("Required class %s is not on the classpath.", getAnnotationType().getName()); } if (templateType.getModifiers().contains(Modifier.PRIVATE)) { typeSystem.addError("A @%s must have at least package protected visibility.", getAnnotationType().getName()); } if (templateType.getModifiers().contains(Modifier.FINAL)) { typeSystem.addError("The @%s must not be final.", getAnnotationType().getName()); } if (typeSystem.hasErrors()) { return typeSystem; } List types = parseTypes(typeSystem); TypeMirror genericType = context.getType(Object.class); TypeData voidType = new TypeData(typeSystem, types.size(), null, context.getType(void.class), context.getType(Void.class)); types.add(voidType); typeSystem.setTypes(types); if (typeSystem.hasErrors()) { return typeSystem; } typeSystem.setGenericType(genericType); typeSystem.setVoidType(voidType); verifyExclusiveMethodAnnotation(typeSystem, TypeCast.class, TypeCheck.class); List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(templateType)); List implicitCasts = new ImplicitCastParser(context, typeSystem).parse(elements); List casts = new TypeCastParser(context, typeSystem).parse(elements); List checks = new TypeCheckParser(context, typeSystem).parse(elements); if (casts == null || checks == null || implicitCasts == null) { return typeSystem; } typeSystem.setImplicitCasts(implicitCasts); typeSystem.setCasts(casts); typeSystem.setChecks(checks); if (typeSystem.hasErrors()) { return typeSystem; } for (TypeCheckData check : checks) { check.getCheckedType().addTypeCheck(check); } for (TypeCastData cast : casts) { cast.getTargetType().addTypeCast(cast); } verifyGenericTypeChecksAndCasts(typeSystem); verifyMethodSignatures(typeSystem); verifyNamesUnique(typeSystem); return typeSystem; } private void verifyExclusiveMethodAnnotation(Template template, Class... annotationTypes) { List methods = ElementFilter.methodsIn(template.getTemplateType().getEnclosedElements()); for (ExecutableElement method : methods) { List foundAnnotations = new ArrayList<>(); for (int i = 0; i < annotationTypes.length; i++) { Class annotationType = annotationTypes[i]; AnnotationMirror mirror = ElementUtils.findAnnotationMirror(context.getEnvironment(), method, annotationType); if (mirror != null) { foundAnnotations.add(mirror); } } if (foundAnnotations.size() > 1) { List annotationNames = new ArrayList<>(); for (AnnotationMirror mirror : foundAnnotations) { annotationNames.add("@" + ElementUtils.getSimpleName(mirror.getAnnotationType())); } template.addError("Non exclusive usage of annotations %s.", annotationNames); } } } private static void verifyGenericTypeChecksAndCasts(TypeSystemData typeSystem) { for (TypeData type : typeSystem.getTypes()) { if (!type.getTypeChecks().isEmpty()) { boolean hasGeneric = false; for (TypeCheckData typeCheck : type.getTypeChecks()) { if (typeCheck.isGeneric()) { hasGeneric = true; break; } } if (!hasGeneric) { type.addError("No generic but specific @%s method %s for type %s specified. " + "Specify a generic @%s method with parameter type %s to resolve this.", TypeCheck.class.getSimpleName(), TypeSystemCodeGenerator.isTypeMethodName(type), ElementUtils.getSimpleName(type.getBoxedType()), TypeCheck.class.getSimpleName(), Object.class.getSimpleName()); } } if (!type.getTypeCasts().isEmpty()) { boolean hasGeneric = false; for (TypeCastData typeCast : type.getTypeCasts()) { if (typeCast.isGeneric()) { hasGeneric = true; break; } } if (!hasGeneric) { type.addError("No generic but specific @%s method %s for type %s specified. " + "Specify a generic @%s method with parameter type %s to resolve this.", TypeCast.class.getSimpleName(), TypeSystemCodeGenerator.asTypeMethodName(type), ElementUtils.getSimpleName(type.getBoxedType()), TypeCast.class.getSimpleName(), Object.class.getSimpleName()); } } } } private List parseTypes(TypeSystemData typeSystem) { List types = new ArrayList<>(); List typeMirrors = ElementUtils.getAnnotationValueList(TypeMirror.class, typeSystem.getTemplateTypeAnnotation(), "value"); if (typeMirrors.isEmpty()) { typeSystem.addError("At least one type must be defined."); return types; } final AnnotationValue annotationValue = ElementUtils.getAnnotationValue(typeSystem.getTemplateTypeAnnotation(), "value"); final TypeMirror objectType = context.getType(Object.class); int index = 0; for (TypeMirror primitiveType : typeMirrors) { TypeMirror primitive = ElementUtils.fillInGenericWildcards(primitiveType); TypeMirror boxedType = ElementUtils.boxType(context, primitive); TypeData typeData = new TypeData(typeSystem, index, annotationValue, primitive, boxedType); if (isPrimitiveWrapper(primitive)) { typeData.addError("Types must not contain primitive wrapper types."); } if (ElementUtils.typeEquals(boxedType, objectType)) { typeData.addError("Types must not contain the generic type java.lang.Object."); } types.add(typeData); index++; } verifyTypeOrder(types); types.add(new TypeData(typeSystem, index, annotationValue, objectType, objectType)); return types; } private static void verifyTypeOrder(List types) { Map> invalidTypes = new HashMap<>(); for (int i = types.size() - 1; i >= 0; i--) { TypeData typeData = types.get(i); TypeMirror type = typeData.getBoxedType(); if (invalidTypes.containsKey(ElementUtils.getQualifiedName(type))) { typeData.addError("Invalid type order. The type(s) %s are inherited from a earlier defined type %s.", invalidTypes.get(ElementUtils.getQualifiedName(type)), ElementUtils.getQualifiedName(type)); } TypeElement element = ElementUtils.fromTypeMirror(type); List nextInvalidTypes = new ArrayList<>(); if (element != null) { nextInvalidTypes.addAll(ElementUtils.getQualifiedSuperTypeNames(element)); } nextInvalidTypes.add(getQualifiedName(type)); for (String qualifiedName : nextInvalidTypes) { List inheritedTypes = invalidTypes.get(qualifiedName); if (inheritedTypes == null) { inheritedTypes = new ArrayList<>(); invalidTypes.put(qualifiedName, inheritedTypes); } inheritedTypes.add(ElementUtils.getQualifiedName(typeData.getBoxedType())); } } } private boolean isPrimitiveWrapper(TypeMirror type) { Types types = context.getEnvironment().getTypeUtils(); for (TypeKind kind : TypeKind.values()) { if (!kind.isPrimitive()) { continue; } if (ElementUtils.typeEquals(type, types.boxedClass(types.getPrimitiveType(kind)).asType())) { return true; } } return false; } private void verifyMethodSignatures(TypeSystemData typeSystem) { Set generatedIsMethodNames = new HashSet<>(); Set generatedAsMethodNames = new HashSet<>(); Set generatedExpectMethodNames = new HashSet<>(); for (TypeData typeData : typeSystem.getTypes()) { generatedIsMethodNames.add(TypeSystemCodeGenerator.isTypeMethodName(typeData)); generatedAsMethodNames.add(TypeSystemCodeGenerator.asTypeMethodName(typeData)); generatedExpectMethodNames.add(TypeSystemCodeGenerator.expectTypeMethodName(typeData)); } List methods = ElementFilter.methodsIn(typeSystem.getTemplateType().getEnclosedElements()); for (ExecutableElement method : methods) { if (method.getModifiers().contains(Modifier.PRIVATE)) { // will not conflict overridden methods continue; } else if (method.getParameters().size() != 1) { continue; } String methodName = method.getSimpleName().toString(); if (generatedIsMethodNames.contains(methodName)) { verifyIsMethod(typeSystem, method); } else if (generatedAsMethodNames.contains(methodName)) { verifyAsMethod(typeSystem, method); } else if (generatedExpectMethodNames.contains(methodName)) { verifyExpectMethod(typeSystem); } } } private boolean verifyIsMethod(TypeSystemData typeSystem, ExecutableElement method) { AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, TypeCheck.class); if (mirror == null) { typeSystem.addError("Method starting with the pattern is${typeName} must be annotated with @%s.", TypeCheck.class.getSimpleName()); return false; } return true; } private boolean verifyAsMethod(TypeSystemData typeSystem, ExecutableElement method) { AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, TypeCast.class); if (mirror == null) { typeSystem.addError("Method starting with the pattern as${typeName} must be annotated with @%s.", TypeCast.class.getSimpleName()); return false; } return true; } private static boolean verifyExpectMethod(TypeSystemData typeSystem) { typeSystem.addError("Method starting with the pattern expect${typeName} must not be declared manually."); return false; } private static void verifyNamesUnique(TypeSystemData typeSystem) { List types = typeSystem.getTypes(); for (int i = 0; i < types.size(); i++) { for (int j = i + 1; j < types.size(); j++) { String name1 = ElementUtils.getSimpleName(types.get(i).getBoxedType()); String name2 = ElementUtils.getSimpleName(types.get(j).getBoxedType()); if (name1.equalsIgnoreCase(name2)) { typeSystem.addError("Two types result in the same name: %s, %s.", name1, name2); } } } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/TypeCheckParser.java0000644000000000000000000000476212445312576027160 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import javax.lang.model.element.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.model.*; class TypeCheckParser extends TypeSystemMethodParser { public TypeCheckParser(ProcessorContext context, TypeSystemData typeSystem) { super(context, typeSystem); } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { TypeData targetType = findTypeByMethodName(method.getSimpleName().toString(), "is"); if (targetType == null) { return null; } MethodSpec spec = new MethodSpec(new ParameterSpec("returnType", getContext().getType(boolean.class))); spec.addRequired(new ParameterSpec("value", getTypeSystem().getPrimitiveTypeMirrors(), getTypeSystem().getTypeIdentifiers())); return spec; } @Override public TypeCheckData create(TemplateMethod method, boolean invalid) { TypeData checkedType = findTypeByMethodName(method, "is"); assert checkedType != null; Parameter parameter = method.findParameter("valueValue"); assert parameter != null; return new TypeCheckData(method, checkedType, parameter.getTypeSystemType()); } @Override public Class getAnnotationType() { return TypeCheck.class; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/SpecializationGroup.java0000644000000000000000000003654712445312576030125 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.util.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; import com.oracle.truffle.dsl.processor.model.TemplateMethod.TypeSignature; /** * Class creates groups of specializations to optimize the layout of generated executeAndSpecialize * and generic execute methods. */ public final class SpecializationGroup { private final List assumptions; private final List typeGuards; private final List guards; private final NodeData node; private final SpecializationData specialization; private final List children = new ArrayList<>(); private SpecializationGroup parent; private SpecializationGroup(SpecializationData data) { this.node = data.getNode(); this.assumptions = new ArrayList<>(); this.typeGuards = new ArrayList<>(); this.guards = new ArrayList<>(); this.specialization = data; this.assumptions.addAll(data.getAssumptions()); TypeSignature sig = data.getTypeSignature(); for (int i = 1; i < sig.size(); i++) { typeGuards.add(new TypeGuard(sig.get(i), i - 1)); } this.guards.addAll(data.getGuards()); } public SpecializationGroup(List children, List assumptionMatches, List typeGuardsMatches, List guardMatches) { assert !children.isEmpty() : "children must not be empty"; this.assumptions = assumptionMatches; this.typeGuards = typeGuardsMatches; this.guards = guardMatches; this.node = children.get(0).node; this.specialization = null; updateChildren(children); } public List getAllGuards() { List collectedGuards = new ArrayList<>(); collectedGuards.addAll(typeGuards); if (parent != null) { collectedGuards.addAll(parent.getAllGuards()); } return collectedGuards; } public TypeGuard findTypeGuard(int signatureIndex) { for (TypeGuard guard : typeGuards) { if (guard.getSignatureIndex() == signatureIndex) { return guard; } } return null; } public List findElseConnectableGuards() { if (!getTypeGuards().isEmpty() || !getAssumptions().isEmpty()) { return Collections.emptyList(); } if (getGuards().isEmpty()) { return Collections.emptyList(); } List elseConnectableGuards = new ArrayList<>(); int guardIndex = 0; while (guardIndex < getGuards().size() && findNegatedGuardInPrevious(getGuards().get(guardIndex)) != null) { elseConnectableGuards.add(getGuards().get(guardIndex)); guardIndex++; } return elseConnectableGuards; } private GuardExpression findNegatedGuardInPrevious(GuardExpression guard) { SpecializationGroup previous = this.getPreviousGroup(); if (previous == null) { return null; } List elseConnectedGuards = previous.findElseConnectableGuards(); if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { return null; } /* Guard is else branch can be connected in previous specialization. */ if (elseConnectedGuards.contains(guard)) { return guard; } GuardExpression previousGuard = previous.getGuards().get(elseConnectedGuards.size()); if (guard.getResolvedGuard().getMethod().equals(previousGuard.getResolvedGuard().getMethod()) && guard.isNegated() != previousGuard.isNegated()) { return guard; } return null; } private void updateChildren(List childs) { if (!children.isEmpty()) { children.clear(); } this.children.addAll(childs); for (SpecializationGroup child : childs) { child.parent = this; } } public SpecializationGroup getParent() { return parent; } public List getAssumptions() { return assumptions; } public List getTypeGuards() { return typeGuards; } public List getGuards() { return guards; } public List getChildren() { return children; } public SpecializationData getSpecialization() { return specialization; } private static SpecializationGroup combine(List groups) { if (groups.isEmpty()) { throw new IllegalArgumentException("empty combinations"); } if (groups.size() == 1) { return null; } List assumptionMatches = new ArrayList<>(); List typeGuardsMatches = new ArrayList<>(); List guardMatches = new ArrayList<>(); SpecializationGroup first = groups.get(0); List others = groups.subList(1, groups.size()); outer: for (String assumption : first.assumptions) { for (SpecializationGroup other : others) { if (!other.assumptions.contains(assumption)) { // assumptions can be combined unordered continue outer; } } assumptionMatches.add(assumption); } outer: for (TypeGuard typeGuard : first.typeGuards) { for (SpecializationGroup other : others) { if (!other.typeGuards.contains(typeGuard)) { // type guards can be combined unordered continue outer; } } typeGuardsMatches.add(typeGuard); } outer: for (GuardExpression guard : first.guards) { for (SpecializationGroup other : others) { if (!other.guards.contains(guard)) { // we must break here. One guard may depend on the other. break outer; } } guardMatches.add(guard); } // check for guards for required type casts for (Iterator iterator = guardMatches.iterator(); iterator.hasNext();) { GuardExpression guardMatch = iterator.next(); int signatureIndex = 0; for (Parameter parameter : guardMatch.getResolvedGuard().getParameters()) { signatureIndex++; if (!parameter.getSpecification().isSignature()) { continue; } TypeMirror guardType = parameter.getType(); // object guards can be safely moved up if (ElementUtils.isObject(guardType)) { continue; } // generic guards can be safely moved up SpecializationData generic = first.node.getGenericSpecialization(); if (generic != null) { Parameter genericParameter = generic.findParameter(parameter.getLocalName()); if (genericParameter != null && ElementUtils.typeEquals(genericParameter.getType(), guardType)) { continue; } } // signature index required for moving up guards if (containsIndex(typeGuardsMatches, signatureIndex) || (first.getParent() != null && first.getParent().containsTypeGuardIndex(signatureIndex))) { continue; } iterator.remove(); break; } } if (assumptionMatches.isEmpty() && typeGuardsMatches.isEmpty() && guardMatches.isEmpty()) { return null; } for (SpecializationGroup group : groups) { group.assumptions.removeAll(assumptionMatches); group.typeGuards.removeAll(typeGuardsMatches); group.guards.removeAll(guardMatches); } List newChildren = new ArrayList<>(groups); return new SpecializationGroup(newChildren, assumptionMatches, typeGuardsMatches, guardMatches); } private boolean containsTypeGuardIndex(int index) { if (containsIndex(typeGuards, index)) { return true; } if (parent != null) { return parent.containsTypeGuardIndex(index); } return false; } private static boolean containsIndex(List typeGuards, int signatureIndex) { for (TypeGuard guard : typeGuards) { if (guard.signatureIndex == signatureIndex) { return true; } } return false; } public static SpecializationGroup create(SpecializationData specialization) { return new SpecializationGroup(specialization); } public static SpecializationGroup create(List specializations) { List groups = new ArrayList<>(); for (SpecializationData specialization : specializations) { groups.add(new SpecializationGroup(specialization)); } return new SpecializationGroup(createCombinationalGroups(groups), Collections. emptyList(), Collections. emptyList(), Collections. emptyList()); } @Override public String toString() { return "SpecializationGroup [assumptions=" + assumptions + ", typeGuards=" + typeGuards + ", guards=" + guards + "]"; } private static List createCombinationalGroups(List groups) { if (groups.size() <= 1) { return groups; } List newGroups = new ArrayList<>(); int i = 0; for (i = 0; i < groups.size();) { SpecializationGroup combined = null; for (int j = groups.size(); j > i + 1; j--) { combined = combine(groups.subList(i, j)); if (combined != null) { break; } } SpecializationGroup newGroup; if (combined == null) { newGroup = groups.get(i); i++; } else { newGroup = combined; List originalGroups = new ArrayList<>(combined.children); combined.updateChildren(createCombinationalGroups(originalGroups)); i += originalGroups.size(); } newGroups.add(newGroup); } return newGroups; } public SpecializationGroup getPreviousGroup() { if (parent == null || parent.children.isEmpty()) { return null; } int index = parent.children.indexOf(this); if (index <= 0) { return null; } return parent.children.get(index - 1); } public int getUncheckedSpecializationIndex() { int groupMaxIndex = getMaxSpecializationIndex(); int genericIndex = node.getSpecializations().indexOf(node.getGenericSpecialization()); if (groupMaxIndex >= genericIndex) { // no minimum state check for an generic index groupMaxIndex = -1; } if (groupMaxIndex > -1) { // no minimum state check if already checked by parent group int parentMaxIndex = -1; if (getParent() != null) { parentMaxIndex = getParent().getMaxSpecializationIndex(); } if (groupMaxIndex == parentMaxIndex) { groupMaxIndex = -1; } } return groupMaxIndex; } public int getMaxSpecializationIndex() { if (specialization != null) { return specialization.getNode().getSpecializations().indexOf(specialization); } else { int max = Integer.MIN_VALUE; for (SpecializationGroup childGroup : getChildren()) { max = Math.max(max, childGroup.getMaxSpecializationIndex()); } return max; } } public static final class TypeGuard { private final int signatureIndex; private final TypeData type; public TypeGuard(TypeData type, int signatureIndex) { this.type = type; this.signatureIndex = signatureIndex; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + signatureIndex; result = prime * result + type.hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } else if (obj == null) { return false; } else if (getClass() != obj.getClass()) { return false; } TypeGuard other = (TypeGuard) obj; if (signatureIndex != other.signatureIndex) { return false; } else if (!type.equals(other.type)) { return false; } return true; } public int getSignatureIndex() { return signatureIndex; } public TypeData getType() { return type; } } public boolean isTypeGuardUsedInAnyGuardBelow(ProcessorContext context, SpecializationData source, TypeGuard typeGuard) { NodeExecutionData execution = source.getNode().getChildExecutions().get(typeGuard.getSignatureIndex()); for (GuardExpression guard : guards) { List guardParameters = guard.getResolvedGuard().findByExecutionData(execution); Parameter sourceParameter = source.getSignatureParameter(typeGuard.getSignatureIndex()); for (Parameter guardParameter : guardParameters) { if (sourceParameter.getTypeSystemType().needsCastTo(guardParameter.getType())) { return true; } } } for (SpecializationGroup group : getChildren()) { if (group.isTypeGuardUsedInAnyGuardBelow(context, source, typeGuard)) { return true; } } return false; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/MethodSpecParser.java0000644000000000000000000002671212445312576027333 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; public final class MethodSpecParser { private boolean emitErrors = true; private boolean useVarArgs = false; private final Template template; public MethodSpecParser(Template template) { this.template = template; } public Template getTemplate() { return template; } public TypeSystemData getTypeSystem() { return template.getTypeSystem(); } public boolean isEmitErrors() { return emitErrors; } public boolean isUseVarArgs() { return useVarArgs; } public void setEmitErrors(boolean emitErrors) { this.emitErrors = emitErrors; } public void setUseVarArgs(boolean useVarArgs) { this.useVarArgs = useVarArgs; } public TemplateMethod parse(MethodSpec methodSpecification, ExecutableElement method, AnnotationMirror annotation, int naturalOrder) { if (methodSpecification == null) { return null; } methodSpecification.applyTypeDefinitions("types"); String id = method.getSimpleName().toString(); TypeMirror returnType = method.getReturnType(); List parameterTypes = new ArrayList<>(); for (VariableElement var : method.getParameters()) { parameterTypes.add(var.asType()); } return parseImpl(methodSpecification, naturalOrder, id, method, annotation, returnType, parameterTypes); } public TemplateMethod parseImpl(MethodSpec methodSpecification, int naturalOrder, String id, ExecutableElement method, AnnotationMirror annotation, TypeMirror returnType, List parameterTypes) { ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); Parameter returnTypeMirror = matchParameter(returnTypeSpec, returnType, -1, -1); if (returnTypeMirror == null) { if (emitErrors) { TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()); String expectedReturnType = returnTypeSpec.toSignatureString(true); String actualReturnType = ElementUtils.getSimpleName(returnType); String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType, methodSpecification.toSignatureString(method.getSimpleName().toString())); invalidMethod.addError(message); return invalidMethod; } else { return null; } } List parameters = parseParameters(methodSpecification, parameterTypes, isUseVarArgs() && method != null ? method.isVarArgs() : false); if (parameters == null) { if (isEmitErrors() && method != null) { TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()); String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(method), methodSpecification.toSignatureString(method.getSimpleName().toString())); invalidMethod.addError(message); return invalidMethod; } else { return null; } } return new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, parameters); } private static String createActualSignature(ExecutableElement method) { StringBuilder b = new StringBuilder("("); String sep = ""; if (method != null) { for (VariableElement var : method.getParameters()) { b.append(sep); b.append(ElementUtils.getSimpleName(var.asType())); sep = ", "; } } b.append(")"); return b.toString(); } /* * Parameter parsing tries to parse required arguments starting from offset 0 with increasing * offset until it finds a signature end that matches the required specification. If there is no * end matching the required arguments, parsing fails. Parameters prior to the parsed required * ones are cut and used to parse the optional parameters. */ private List parseParameters(MethodSpec spec, List parameterTypes, boolean varArgs) { List parsedRequired = null; int offset = 0; for (; offset <= parameterTypes.size(); offset++) { List parameters = new ArrayList<>(); parameters.addAll(parameterTypes.subList(offset, parameterTypes.size())); parsedRequired = parseParametersRequired(spec, parameters, varArgs); if (parsedRequired != null) { break; } } if (parsedRequired == null) { return null; } if (parsedRequired.isEmpty() && offset == 0) { offset = parameterTypes.size(); } List potentialOptionals = parameterTypes.subList(0, offset); List parsedOptionals = parseParametersOptional(spec, potentialOptionals); if (parsedOptionals == null) { return null; } List finalParameters = new ArrayList<>(); finalParameters.addAll(parsedOptionals); finalParameters.addAll(parsedRequired); return finalParameters; } private List parseParametersOptional(MethodSpec spec, List types) { List parsedParams = new ArrayList<>(); int typeStartIndex = 0; List specifications = spec.getOptional(); outer: for (int specIndex = 0; specIndex < specifications.size(); specIndex++) { ParameterSpec specification = specifications.get(specIndex); for (int typeIndex = typeStartIndex; typeIndex < types.size(); typeIndex++) { TypeMirror actualType = types.get(typeIndex); Parameter optionalParam = matchParameter(specification, actualType, -1, -1); if (optionalParam != null) { parsedParams.add(optionalParam); typeStartIndex = typeIndex + 1; continue outer; } } } if (typeStartIndex < types.size()) { // not enough types found return null; } return parsedParams; } private List parseParametersRequired(MethodSpec spec, List types, boolean typeVarArgs) { List parsedParams = new ArrayList<>(); List specifications = spec.getRequired(); boolean specVarArgs = spec.isVariableRequiredParameters(); int typeIndex = 0; int specificationIndex = 0; ParameterSpec specification; while ((specification = nextSpecification(specifications, specificationIndex, specVarArgs)) != null) { TypeMirror actualType = nextActualType(types, typeIndex, typeVarArgs); if (actualType == null) { if (spec.isIgnoreAdditionalSpecifications()) { break; } return null; } int typeVarArgsIndex = typeVarArgs ? typeIndex - types.size() + 1 : -1; int specVarArgsIndex = specVarArgs ? specificationIndex - specifications.size() + 1 : -1; if (typeVarArgsIndex >= 0 && specVarArgsIndex >= 0) { // both specifications and types have a variable number of arguments // we would get into an endless loop if we would continue break; } Parameter resolvedParameter = matchParameter(specification, actualType, specVarArgsIndex, typeVarArgsIndex); if (resolvedParameter == null) { return null; } parsedParams.add(resolvedParameter); typeIndex++; specificationIndex++; } if (typeIndex < types.size()) { // additional types available if (spec.isIgnoreAdditionalParameters()) { return parsedParams; } else { return null; } } return parsedParams; } private static ParameterSpec nextSpecification(List specifications, int specIndex, boolean varArgs) { if (varArgs && specIndex >= specifications.size() - 1 && !specifications.isEmpty()) { return specifications.get(specifications.size() - 1); } else if (specIndex < specifications.size()) { return specifications.get(specIndex); } else { return null; } } private static TypeMirror nextActualType(List types, int typeIndex, boolean varArgs) { if (varArgs && typeIndex >= types.size() - 1 && !types.isEmpty()) { // unpack varargs array argument TypeMirror actualType = types.get(types.size() - 1); if (actualType.getKind() == TypeKind.ARRAY) { actualType = ((ArrayType) actualType).getComponentType(); } return actualType; } else if (typeIndex < types.size()) { return types.get(typeIndex); } else { return null; } } private Parameter matchParameter(ParameterSpec specification, TypeMirror mirror, int specificationIndex, int varArgsIndex) { TypeMirror resolvedType = mirror; if (hasError(resolvedType)) { return null; } if (!specification.matches(resolvedType)) { return null; } TypeData resolvedTypeData = getTypeSystem().findTypeData(resolvedType); if (resolvedTypeData != null) { return new Parameter(specification, resolvedTypeData, specificationIndex, varArgsIndex); } else { return new Parameter(specification, resolvedType, specificationIndex, varArgsIndex); } } } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/SpecializationMethodParser.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/SpecializationMethodParser.ja0000644000000000000000000001244312445312576031064 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; import com.oracle.truffle.dsl.processor.model.SpecializationData.SpecializationKind; public class SpecializationMethodParser extends NodeMethodParser { public SpecializationMethodParser(ProcessorContext context, NodeData operation) { super(context, operation); } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { return createDefaultMethodSpec(method, mirror, true, null); } @Override public SpecializationData create(TemplateMethod method, boolean invalid) { return parseSpecialization(method); } @Override public Class getAnnotationType() { return Specialization.class; } private SpecializationData parseSpecialization(TemplateMethod method) { AnnotationValue rewriteValue = ElementUtils.getAnnotationValue(method.getMarkerAnnotation(), "rewriteOn"); List exceptionTypes = ElementUtils.getAnnotationValueList(TypeMirror.class, method.getMarkerAnnotation(), "rewriteOn"); List exceptionData = new ArrayList<>(); for (TypeMirror exceptionType : exceptionTypes) { SpecializationThrowsData throwsData = new SpecializationThrowsData(method.getMarkerAnnotation(), rewriteValue, exceptionType); if (!ElementUtils.canThrowType(method.getMethod().getThrownTypes(), exceptionType)) { throwsData.addError("Method must specify a throws clause with the exception type '%s'.", ElementUtils.getQualifiedName(exceptionType)); } exceptionData.add(throwsData); } Collections.sort(exceptionData, new Comparator() { @Override public int compare(SpecializationThrowsData o1, SpecializationThrowsData o2) { return ElementUtils.compareByTypeHierarchy(o1.getJavaClass(), o2.getJavaClass()); } }); SpecializationData specialization = new SpecializationData(getNode(), method, SpecializationKind.SPECIALIZED, exceptionData); String insertBeforeName = ElementUtils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "insertBefore"); if (!insertBeforeName.equals("")) { specialization.setInsertBeforeName(insertBeforeName); } List guardDefs = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards"); List guardExpressions = new ArrayList<>(); for (String guardDef : guardDefs) { guardExpressions.add(new GuardExpression(guardDef, true)); } specialization.setGuards(guardExpressions); List containsDefs = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "contains"); Set containsNames = specialization.getContainsNames(); containsNames.clear(); if (containsDefs != null) { for (String include : containsDefs) { if (!containsNames.contains(include)) { specialization.getContainsNames().add(include); } else { AnnotationValue value = ElementUtils.getAnnotationValue(specialization.getMarkerAnnotation(), "contains"); specialization.addError(value, "Duplicate contains declaration '%s'.", include); } } } List assumptionDefs = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "assumptions"); specialization.setAssumptions(assumptionDefs); for (String assumption : assumptionDefs) { if (!getNode().getAssumptions().contains(assumption)) { specialization.addError("Undeclared assumption '%s' used. Use @NodeAssumptions to declare them.", assumption); } } return specialization; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/parser/TemplateMethodParser.java0000644000000000000000000001172112445312576030206 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.parser; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.*; public abstract class TemplateMethodParser { protected final T template; private final ProcessorContext context; private final MethodSpecParser parser; private boolean parseNullOnError; public TemplateMethodParser(ProcessorContext context, T template) { this.template = template; this.context = context; this.parser = new MethodSpecParser(template); } public void setParseNullOnError(boolean parseNullOnError) { this.parseNullOnError = parseNullOnError; } public boolean isParseNullOnError() { return parseNullOnError; } public MethodSpecParser getParser() { return parser; } public ProcessorContext getContext() { return context; } public TypeSystemData getTypeSystem() { return template.getTypeSystem(); } public abstract MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror); public abstract E create(TemplateMethod method, boolean invalid); public abstract boolean isParsable(ExecutableElement method); public Class getAnnotationType() { return null; } public final List parse(List elements) { List methods = new ArrayList<>(); methods.addAll(ElementFilter.methodsIn(elements)); List parsedMethods = new ArrayList<>(); boolean valid = true; int naturalOrder = 0; for (ExecutableElement method : methods) { if (!isParsable(method)) { continue; } Class annotationType = getAnnotationType(); AnnotationMirror mirror = null; if (annotationType != null) { mirror = ElementUtils.findAnnotationMirror(getContext().getEnvironment(), method, annotationType); } E parsedMethod = parse(naturalOrder, method, mirror); if (method.getModifiers().contains(Modifier.PRIVATE) && parser.isEmitErrors()) { parsedMethod.addError("Method annotated with @%s must not be private.", getAnnotationType().getSimpleName()); parsedMethods.add(parsedMethod); valid = false; continue; } if (parsedMethod != null) { parsedMethods.add(parsedMethod); } else { valid = false; } naturalOrder++; } Collections.sort(parsedMethods); if (!valid && isParseNullOnError()) { return null; } return parsedMethods; } private E parse(int naturalOrder, ExecutableElement method, AnnotationMirror annotation) { MethodSpec methodSpecification = createSpecification(method, annotation); if (methodSpecification == null) { return null; } TemplateMethod templateMethod = parser.parse(methodSpecification, method, annotation, naturalOrder); if (templateMethod != null) { return create(templateMethod, templateMethod.hasErrors()); } return null; } public final E create(String id, int naturalOrder, ExecutableElement methodMetadata, AnnotationMirror mirror, TypeMirror returnType, List parameterTypes) { TemplateMethod method = parser.parseImpl(createSpecification(methodMetadata, mirror), naturalOrder, id, methodMetadata, mirror, returnType, parameterTypes); if (method != null) { return create(method, method.hasErrors()); } return null; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/0000755000000000000000000000000012460760144022670 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/transform/0000755000000000000000000000000012460760144024703 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/transform/OrganizedImports.java0000644000000000000000000004417212445312576031063 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.transform; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; public final class OrganizedImports { private final Map classImportUsage = new HashMap<>(); private final Map staticImportUsage = new HashMap<>(); private final Map> autoImportCache = new HashMap<>(); private final CodeTypeElement topLevelClass; private OrganizedImports(CodeTypeElement topLevelClass) { this.topLevelClass = topLevelClass; } public static OrganizedImports organize(CodeTypeElement topLevelClass) { OrganizedImports organized = new OrganizedImports(topLevelClass); organized.organizeImpl(); return organized; } private void organizeImpl() { ImportTypeReferenceVisitor reference = new ImportTypeReferenceVisitor(); topLevelClass.accept(reference, null); } public String createTypeReference(Element enclosedElement, TypeMirror type) { switch (type.getKind()) { case BOOLEAN: case BYTE: case CHAR: case DOUBLE: case FLOAT: case SHORT: case INT: case LONG: case VOID: return ElementUtils.getSimpleName(type); case DECLARED: return createDeclaredTypeName(enclosedElement, (DeclaredType) type); case ARRAY: return createTypeReference(enclosedElement, ((ArrayType) type).getComponentType()) + "[]"; case WILDCARD: return createWildcardName(enclosedElement, (WildcardType) type); case TYPEVAR: return "?"; default: throw new RuntimeException("Unknown type specified " + type.getKind() + " mirror: " + type); } } public String createStaticFieldReference(Element enclosedElement, TypeMirror type, String fieldName) { return createStaticReference(enclosedElement, type, fieldName); } public String createStaticMethodReference(Element enclosedElement, TypeMirror type, String methodName) { return createStaticReference(enclosedElement, type, methodName); } private String createStaticReference(Element enclosedElement, TypeMirror type, String name) { String qualifiedName = staticImportUsage.get(name); if (qualifiedName == null) { // ambiguous import return createTypeReference(enclosedElement, type) + "." + name; } else { // import declared and not ambiguous return name; } } private String createWildcardName(Element enclosedElement, WildcardType type) { StringBuilder b = new StringBuilder(); if (type.getExtendsBound() != null) { b.append("? extends ").append(createTypeReference(enclosedElement, type.getExtendsBound())); } else if (type.getSuperBound() != null) { b.append("? super ").append(createTypeReference(enclosedElement, type.getExtendsBound())); } else { b.append("?"); } return b.toString(); } private String createDeclaredTypeName(Element enclosedElement, DeclaredType type) { String name = ElementUtils.fixECJBinaryNameIssue(type.asElement().getSimpleName().toString()); if (classImportUsage.containsKey(name)) { String qualifiedImport = classImportUsage.get(name); String qualifiedName = ElementUtils.getEnclosedQualifiedName(type); if (!qualifiedName.equals(qualifiedImport)) { name = qualifiedName; } } List genericTypes = type.getTypeArguments(); if (genericTypes.size() == 0) { return name; } StringBuilder b = new StringBuilder(name); b.append("<"); for (int i = 0; i < genericTypes.size(); i++) { TypeMirror genericType = i < genericTypes.size() ? genericTypes.get(i) : null; if (genericType != null) { b.append(createTypeReference(enclosedElement, genericType)); } else { b.append("?"); } if (i < genericTypes.size() - 1) { b.append(", "); } } b.append(">"); return b.toString(); } public Set generateImports() { Set imports = new HashSet<>(); imports.addAll(generateImports(classImportUsage)); imports.addAll(generateStaticImports(staticImportUsage)); return imports; } private boolean needsImport(Element enclosed, TypeMirror importType) { String importPackagName = getPackageName(importType); TypeElement enclosedElement = findNearestEnclosingType(enclosed); if (importPackagName == null) { return false; } else if (importPackagName.equals("java.lang")) { return false; } else if (importPackagName.equals(getPackageName(topLevelClass)) && ElementUtils.isTopLevelClass(importType)) { return false; // same package name -> no import } String enclosedElementId = ElementUtils.getUniqueIdentifier(enclosedElement.asType()); Set autoImportedTypes = autoImportCache.get(enclosedElementId); if (autoImportedTypes == null) { List elements = ElementUtils.getElementHierarchy(enclosedElement); autoImportedTypes = new HashSet<>(); for (Element element : elements) { if (element.getKind().isClass()) { collectSuperTypeImports((TypeElement) element, autoImportedTypes); collectInnerTypeImports((TypeElement) element, autoImportedTypes); } } autoImportCache.put(enclosedElementId, autoImportedTypes); } String qualifiedName = getQualifiedName(importType); if (autoImportedTypes.contains(qualifiedName)) { return false; } return true; } private static Set generateImports(Map symbols) { TreeSet importObjects = new TreeSet<>(); for (String symbol : symbols.keySet()) { String packageName = symbols.get(symbol); if (packageName != null) { importObjects.add(new CodeImport(packageName, symbol, false)); } } return importObjects; } private static void collectInnerTypeImports(TypeElement e, Set autoImportedTypes) { autoImportedTypes.add(getQualifiedName(e)); for (TypeElement innerClass : ElementFilter.typesIn(e.getEnclosedElements())) { collectInnerTypeImports(innerClass, autoImportedTypes); } } private static void collectSuperTypeImports(TypeElement e, Set autoImportedTypes) { List superTypes = getSuperTypes(e); for (TypeElement superType : superTypes) { List declaredTypes = getDeclaredTypes(superType); for (TypeElement declaredType : declaredTypes) { autoImportedTypes.add(getQualifiedName(declaredType)); } } } private Set generateStaticImports(Map toGenerate) { Set autoImportedStaticTypes = new HashSet<>(); // if type is declared inside a super type of this class -> no import autoImportedStaticTypes.add(getQualifiedName(topLevelClass)); autoImportedStaticTypes.addAll(getQualifiedSuperTypeNames(topLevelClass)); TreeSet importObjects = new TreeSet<>(); for (String symbol : toGenerate.keySet()) { String qualifiedName = toGenerate.get(symbol); if (qualifiedName == null) { // ambiguous continue; } // not not import if (autoImportedStaticTypes.contains(qualifiedName)) { continue; } importObjects.add(new CodeImport(qualifiedName, symbol, true)); } return importObjects; } private abstract static class TypeReferenceVisitor extends CodeElementScanner { @Override public void visitTree(CodeTree e, Void p, Element enclosing) { if (e.getCodeKind() == CodeTreeKind.STATIC_FIELD_REFERENCE) { visitStaticFieldReference(enclosing, e.getType(), e.getString()); } else if (e.getCodeKind() == CodeTreeKind.STATIC_METHOD_REFERENCE) { visitStaticMethodReference(enclosing, e.getType(), e.getString()); } else if (e.getType() != null) { visitTypeReference(enclosing, e.getType()); } super.visitTree(e, p, enclosing); } @Override public Void visitExecutable(CodeExecutableElement e, Void p) { visitAnnotations(e, e.getAnnotationMirrors()); if (e.getReturnType() != null) { visitTypeReference(e, e.getReturnType()); } for (TypeMirror type : e.getThrownTypes()) { visitTypeReference(e, type); } return super.visitExecutable(e, p); } @Override public Void visitType(CodeTypeElement e, Void p) { visitAnnotations(e, e.getAnnotationMirrors()); visitTypeReference(e, e.getSuperclass()); for (TypeMirror type : e.getImplements()) { visitTypeReference(e, type); } return super.visitType(e, p); } private void visitAnnotations(Element enclosingElement, List mirrors) { for (AnnotationMirror mirror : mirrors) { visitAnnotation(enclosingElement, mirror); } } public void visitAnnotation(Element enclosingElement, AnnotationMirror e) { visitTypeReference(enclosingElement, e.getAnnotationType()); if (!e.getElementValues().isEmpty()) { Map values = e.getElementValues(); Set methodsSet = values.keySet(); List methodsList = new ArrayList<>(); for (ExecutableElement method : methodsSet) { if (values.get(method) == null) { continue; } methodsList.add(method); } for (int i = 0; i < methodsList.size(); i++) { AnnotationValue value = values.get(methodsList.get(i)); visitAnnotationValue(enclosingElement, value); } } } public void visitAnnotationValue(Element enclosingElement, AnnotationValue e) { e.accept(new AnnotationValueReferenceVisitor(enclosingElement), null); } private class AnnotationValueReferenceVisitor extends AbstractAnnotationValueVisitor7 { private final Element enclosingElement; public AnnotationValueReferenceVisitor(Element enclosedElement) { this.enclosingElement = enclosedElement; } @Override public Void visitBoolean(boolean b, Void p) { return null; } @Override public Void visitByte(byte b, Void p) { return null; } @Override public Void visitChar(char c, Void p) { return null; } @Override public Void visitDouble(double d, Void p) { return null; } @Override public Void visitFloat(float f, Void p) { return null; } @Override public Void visitInt(int i, Void p) { return null; } @Override public Void visitLong(long i, Void p) { return null; } @Override public Void visitShort(short s, Void p) { return null; } @Override public Void visitString(String s, Void p) { return null; } @Override public Void visitType(TypeMirror t, Void p) { visitTypeReference(enclosingElement, t); return null; } @Override public Void visitEnumConstant(VariableElement c, Void p) { visitTypeReference(enclosingElement, c.asType()); return null; } @Override public Void visitAnnotation(AnnotationMirror a, Void p) { TypeReferenceVisitor.this.visitAnnotation(enclosingElement, a); return null; } @Override public Void visitArray(List vals, Void p) { for (int i = 0; i < vals.size(); i++) { TypeReferenceVisitor.this.visitAnnotationValue(enclosingElement, vals.get(i)); } return null; } } @Override public Void visitVariable(VariableElement f, Void p) { visitAnnotations(f, f.getAnnotationMirrors()); visitTypeReference(f, f.asType()); return super.visitVariable(f, p); } @Override public void visitImport(CodeImport e, Void p) { } public abstract void visitTypeReference(Element enclosedType, TypeMirror type); public abstract void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName); public abstract void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName); } private class ImportTypeReferenceVisitor extends TypeReferenceVisitor { @Override public void visitStaticFieldReference(Element enclosedType, TypeMirror type, String elementName) { registerSymbol(staticImportUsage, ElementUtils.getQualifiedName(type), elementName); } @Override public void visitStaticMethodReference(Element enclosedType, TypeMirror type, String elementName) { registerSymbol(staticImportUsage, ElementUtils.getQualifiedName(type), elementName); } @Override public void visitTypeReference(Element enclosedType, TypeMirror type) { if (type != null) { switch (type.getKind()) { case BOOLEAN: case BYTE: case CHAR: case DOUBLE: case FLOAT: case SHORT: case INT: case LONG: case VOID: return; case DECLARED: if (needsImport(enclosedType, type)) { DeclaredType declard = (DeclaredType) type; registerSymbol(classImportUsage, ElementUtils.getEnclosedQualifiedName(declard), ElementUtils.getDeclaredName(declard, false)); } for (TypeMirror argument : ((DeclaredType) type).getTypeArguments()) { visitTypeReference(enclosedType, argument); } return; case ARRAY: visitTypeReference(enclosedType, ((ArrayType) type).getComponentType()); return; case WILDCARD: WildcardType wildcard = (WildcardType) type; if (wildcard.getExtendsBound() != null) { visitTypeReference(enclosedType, wildcard.getExtendsBound()); } else if (wildcard.getSuperBound() != null) { visitTypeReference(enclosedType, wildcard.getSuperBound()); } return; case TYPEVAR: return; default: throw new RuntimeException("Unknown type specified " + type.getKind() + " mirror: " + type); } } } private void registerSymbol(Map symbolUsage, String elementQualifiedName, String elementName) { if (symbolUsage.containsKey(elementName)) { String otherQualifiedName = symbolUsage.get(elementName); if (otherQualifiedName == null) { // already registered ambiguous return; } if (!otherQualifiedName.equals(elementQualifiedName)) { symbolUsage.put(elementName, null); } } else { symbolUsage.put(elementName, elementQualifiedName); } } } } ././@LongLink0000644000000000000000000000015400000000000011603 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/transform/GenerateOverrideVisitor.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/transform/GenerateOverrideVisit0000644000000000000000000000464112445312576031111 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.transform; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; public class GenerateOverrideVisitor extends CodeElementScanner { private final DeclaredType overrideType; public GenerateOverrideVisitor(DeclaredType overrideType) { this.overrideType = overrideType; } @Override public Void visitExecutable(CodeExecutableElement e, Void p) { if (!e.getModifiers().contains(Modifier.STATIC) && !e.getModifiers().contains(Modifier.PRIVATE)) { String name = e.getSimpleName().toString(); TypeMirror[] params = e.getParameterTypes(); for (AnnotationMirror mirror : e.getAnnotationMirrors()) { if (ElementUtils.typeEquals(overrideType, mirror.getAnnotationType())) { // already declared (may happen if method copied from super class) return super.visitExecutable(e, p); } } if (isDeclaredMethodInSuperType(e.getEnclosingClass(), name, params)) { e.addAnnotationMirror(new CodeAnnotationMirror(overrideType)); } } return super.visitExecutable(e, p); } } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/transform/AbstractCodeWriter.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/transform/AbstractCodeWriter.ja0000644000000000000000000005663212445312576030773 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.transform; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import java.io.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; public abstract class AbstractCodeWriter extends CodeElementScanner { private static final int MAX_LINE_LENGTH = 200; private static final int LINE_WRAP_INDENTS = 3; private static final String IDENT_STRING = " "; private static final String LN = "\n"; /* unix style */ protected Writer writer; private int indent; private boolean newLine; private int lineLength; private boolean lineWrapping = false; private OrganizedImports imports; protected abstract Writer createWriter(CodeTypeElement clazz) throws IOException; @Override public Void visitType(CodeTypeElement e, Void p) { if (e.isTopLevelClass()) { Writer w = null; try { imports = OrganizedImports.organize(e); w = new TrimTrailingSpaceWriter(createWriter(e)); writer = w; writeRootClass(e); } catch (IOException ex) { throw new RuntimeException(ex); } finally { if (w != null) { try { w.close(); } catch (Throwable e1) { // see eclipse bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=361378 // TODO temporary suppress errors on close. } } writer = null; } } else { writeClassImpl(e); } return null; } private void writeRootClass(CodeTypeElement e) { writeHeader(); write("package ").write(e.getPackageName()).write(";").writeLn(); writeEmptyLn(); Set generateImports = imports.generateImports(); List typeImports = new ArrayList<>(); List staticImports = new ArrayList<>(); for (CodeImport codeImport : generateImports) { if (codeImport.isStaticImport()) { staticImports.add(codeImport); } else { typeImports.add(codeImport); } } Collections.sort(typeImports); Collections.sort(staticImports); for (CodeImport imp : staticImports) { imp.accept(this, null); writeLn(); } if (!staticImports.isEmpty()) { writeEmptyLn(); } for (CodeImport imp : typeImports) { imp.accept(this, null); writeLn(); } if (!typeImports.isEmpty()) { writeEmptyLn(); } writeClassImpl(e); } private String useImport(Element enclosedType, TypeMirror type) { if (imports != null) { return imports.createTypeReference(enclosedType, type); } else { return ElementUtils.getSimpleName(type); } } private void writeClassImpl(CodeTypeElement e) { for (AnnotationMirror annotation : e.getAnnotationMirrors()) { visitAnnotation(e, annotation); writeLn(); } writeModifiers(e.getModifiers()); if (e.getKind() == ElementKind.ENUM) { write("enum "); } else { write("class "); } write(e.getSimpleName()); if (e.getSuperclass() != null && !getQualifiedName(e.getSuperclass()).equals("java.lang.Object")) { write(" extends ").write(useImport(e, e.getSuperclass())); } if (e.getImplements().size() > 0) { write(" implements "); for (int i = 0; i < e.getImplements().size(); i++) { write(useImport(e, e.getImplements().get(i))); if (i < e.getImplements().size() - 1) { write(", "); } } } write(" {").writeLn(); writeEmptyLn(); indent(1); List staticFields = getStaticFields(e); List instanceFields = getInstanceFields(e); for (int i = 0; i < staticFields.size(); i++) { VariableElement field = staticFields.get(i); field.accept(this, null); if (e.getKind() == ElementKind.ENUM && i < staticFields.size() - 1) { write(","); writeLn(); } else { write(";"); writeLn(); } } if (staticFields.size() > 0) { writeEmptyLn(); } for (VariableElement field : instanceFields) { field.accept(this, null); write(";"); writeLn(); } if (instanceFields.size() > 0) { writeEmptyLn(); } for (ExecutableElement method : ElementFilter.constructorsIn(e.getEnclosedElements())) { method.accept(this, null); } for (ExecutableElement method : getInstanceMethods(e)) { method.accept(this, null); } for (ExecutableElement method : getStaticMethods(e)) { method.accept(this, null); } for (TypeElement clazz : e.getInnerClasses()) { clazz.accept(this, null); } dedent(1); write("}"); writeEmptyLn(); } private static List getStaticFields(CodeTypeElement clazz) { List staticFields = new ArrayList<>(); for (VariableElement field : clazz.getFields()) { if (field.getModifiers().contains(Modifier.STATIC)) { staticFields.add(field); } } return staticFields; } private static List getInstanceFields(CodeTypeElement clazz) { List instanceFields = new ArrayList<>(); for (VariableElement field : clazz.getFields()) { if (!field.getModifiers().contains(Modifier.STATIC)) { instanceFields.add(field); } } return instanceFields; } private static List getStaticMethods(CodeTypeElement clazz) { List staticMethods = new ArrayList<>(); for (ExecutableElement method : clazz.getMethods()) { if (method.getModifiers().contains(Modifier.STATIC)) { staticMethods.add(method); } } return staticMethods; } private static List getInstanceMethods(CodeTypeElement clazz) { List instanceMethods = new ArrayList<>(); for (ExecutableElement method : clazz.getMethods()) { if (!method.getModifiers().contains(Modifier.STATIC)) { instanceMethods.add(method); } } return instanceMethods; } @Override public Void visitVariable(VariableElement f, Void p) { Element parent = f.getEnclosingElement(); for (AnnotationMirror annotation : f.getAnnotationMirrors()) { visitAnnotation(f, annotation); write(" "); } CodeTree init = null; if (f instanceof CodeVariableElement) { init = ((CodeVariableElement) f).getInit(); } if (parent.getKind() == ElementKind.ENUM && f.getModifiers().contains(Modifier.STATIC)) { write(f.getSimpleName()); if (init != null) { write("("); visitTree(init, p, f); write(")"); } } else { Element enclosing = f.getEnclosingElement(); writeModifiers(f.getModifiers()); boolean varArgs = false; if (enclosing.getKind() == ElementKind.METHOD) { ExecutableElement method = (ExecutableElement) enclosing; if (method.isVarArgs() && method.getParameters().indexOf(f) == method.getParameters().size() - 1) { varArgs = true; } } TypeMirror varType = f.asType(); if (varArgs) { if (varType.getKind() == TypeKind.ARRAY) { varType = ((ArrayType) varType).getComponentType(); } write(useImport(f, varType)); write("..."); } else { write(useImport(f, varType)); } write(" "); write(f.getSimpleName()); if (init != null) { write(" = "); visitTree(init, p, f); } } return null; } private void visitAnnotation(Element enclosedElement, AnnotationMirror e) { write("@").write(useImport(enclosedElement, e.getAnnotationType())); if (!e.getElementValues().isEmpty()) { write("("); final ExecutableElement defaultElement = findExecutableElement(e.getAnnotationType(), "value"); Map values = e.getElementValues(); if (defaultElement != null && values.size() == 1 && values.get(defaultElement) != null) { visitAnnotationValue(enclosedElement, values.get(defaultElement)); } else { Set methodsSet = values.keySet(); List methodsList = new ArrayList<>(); for (ExecutableElement method : methodsSet) { if (values.get(method) == null) { continue; } methodsList.add(method); } Collections.sort(methodsList, new Comparator() { @Override public int compare(ExecutableElement o1, ExecutableElement o2) { return o1.getSimpleName().toString().compareTo(o2.getSimpleName().toString()); } }); for (int i = 0; i < methodsList.size(); i++) { ExecutableElement method = methodsList.get(i); AnnotationValue value = values.get(method); write(method.getSimpleName().toString()); write(" = "); visitAnnotationValue(enclosedElement, value); if (i < methodsList.size() - 1) { write(", "); } } } write(")"); } } private void visitAnnotationValue(Element enclosedElement, AnnotationValue e) { e.accept(new AnnotationValueWriterVisitor(enclosedElement), null); } private class AnnotationValueWriterVisitor extends AbstractAnnotationValueVisitor7 { private final Element enclosedElement; public AnnotationValueWriterVisitor(Element enclosedElement) { this.enclosedElement = enclosedElement; } @Override public Void visitBoolean(boolean b, Void p) { write(Boolean.toString(b)); return null; } @Override public Void visitByte(byte b, Void p) { write(Byte.toString(b)); return null; } @Override public Void visitChar(char c, Void p) { write(Character.toString(c)); return null; } @Override public Void visitDouble(double d, Void p) { write(Double.toString(d)); return null; } @Override public Void visitFloat(float f, Void p) { write(Float.toString(f)); return null; } @Override public Void visitInt(int i, Void p) { write(Integer.toString(i)); return null; } @Override public Void visitLong(long i, Void p) { write(Long.toString(i)); return null; } @Override public Void visitShort(short s, Void p) { write(Short.toString(s)); return null; } @Override public Void visitString(String s, Void p) { write("\""); write(s); write("\""); return null; } @Override public Void visitType(TypeMirror t, Void p) { write(useImport(enclosedElement, t)); write(".class"); return null; } @Override public Void visitEnumConstant(VariableElement c, Void p) { write(useImport(enclosedElement, c.asType())); write("."); write(c.getSimpleName().toString()); return null; } @Override public Void visitAnnotation(AnnotationMirror a, Void p) { AbstractCodeWriter.this.visitAnnotation(enclosedElement, a); return null; } @Override public Void visitArray(List vals, Void p) { write("{"); for (int i = 0; i < vals.size(); i++) { AnnotationValue value = vals.get(i); AbstractCodeWriter.this.visitAnnotationValue(enclosedElement, value); if (i < vals.size() - 1) { write(", "); } } write("}"); return null; } } private static ExecutableElement findExecutableElement(DeclaredType type, String name) { List elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements()); for (ExecutableElement executableElement : elements) { if (executableElement.getSimpleName().toString().equals(name)) { return executableElement; } } return null; } @Override public void visitImport(CodeImport e, Void p) { write("import "); if (e.isStaticImport()) { write("static "); } write(e.getPackageName()); write("."); write(e.getSymbolName()); write(";"); } @Override public Void visitExecutable(CodeExecutableElement e, Void p) { for (AnnotationMirror annotation : e.getAnnotationMirrors()) { visitAnnotation(e, annotation); writeLn(); } writeModifiers(e.getModifiers()); if (e.getReturnType() != null) { write(useImport(e, e.getReturnType())); write(" "); } write(e.getSimpleName()); write("("); for (int i = 0; i < e.getParameters().size(); i++) { VariableElement param = e.getParameters().get(i); param.accept(this, p); if (i < e.getParameters().size() - 1) { write(", "); } } write(")"); List throwables = e.getThrownTypes(); if (throwables.size() > 0) { write(" throws "); for (int i = 0; i < throwables.size(); i++) { write(useImport(e, throwables.get(i))); if (i < throwables.size() - 1) { write(", "); } } } if (e.getModifiers().contains(Modifier.ABSTRACT)) { writeLn(";"); } else if (e.getBodyTree() != null) { writeLn(" {"); indent(1); visitTree(e.getBodyTree(), p, e); dedent(1); writeLn("}"); } else if (e.getBody() != null) { write(" {"); write(e.getBody()); writeLn("}"); } else { writeLn(" {"); writeLn("}"); } writeEmptyLn(); return null; } public void foo() { } @Override public void visitTree(CodeTree e, Void p, Element enclosingElement) { CodeTreeKind kind = e.getCodeKind(); switch (kind) { case COMMA_GROUP: List children = e.getEnclosedElements(); if (children != null) { for (int i = 0; i < children.size(); i++) { visitTree(children.get(i), p, enclosingElement); if (i < e.getEnclosedElements().size() - 1) { write(", "); } } } break; case GROUP: super.visitTree(e, p, enclosingElement); break; case INDENT: indent(1); super.visitTree(e, p, enclosingElement); dedent(1); break; case NEW_LINE: writeLn(); break; case STRING: if (e.getString() != null) { write(e.getString()); } else { write("null"); } break; case STATIC_FIELD_REFERENCE: if (e.getString() != null) { write(imports.createStaticFieldReference(enclosingElement, e.getType(), e.getString())); } else { write("null"); } break; case STATIC_METHOD_REFERENCE: if (e.getString() != null) { write(imports.createStaticMethodReference(enclosingElement, e.getType(), e.getString())); } else { write("null"); } break; case TYPE: write(useImport(enclosingElement, e.getType())); break; default: assert false; return; } } protected void writeHeader() { // default implementation does nothing } private void writeModifiers(Set modifiers) { if (modifiers != null) { for (Modifier modifier : modifiers) { write(modifier.toString()); write(" "); } } } private void indent(int count) { indent += count; } private void dedent(int count) { indent -= count; } private void writeLn() { writeLn(""); } protected void writeLn(String text) { write(text); write(LN); lineLength = 0; newLine = true; if (lineWrapping) { dedent(LINE_WRAP_INDENTS); lineWrapping = false; } lineWrapping = false; } private void writeEmptyLn() { writeLn(); } private AbstractCodeWriter write(Name name) { return write(name.toString()); } private AbstractCodeWriter write(String m) { if (m.isEmpty()) { return this; } try { String s = m; lineLength += s.length(); if (newLine && s != LN) { writeIndent(); newLine = false; } if (lineLength > MAX_LINE_LENGTH) { s = wrapLine(s); } writer.write(s); } catch (IOException e) { throw new RuntimeException(e); } return this; } private String wrapLine(String m) throws IOException { assert !m.isEmpty(); char firstCharacter = m.charAt(0); char lastCharacter = m.charAt(m.length() - 1); if (firstCharacter == '\"' && lastCharacter == '\"') { // string line wrapping String string = m.substring(1, m.length() - 1); if (string.isEmpty()) { return m; } // restore original line length lineLength = lineLength - m.length(); int size = 0; for (int i = 0; i < string.length(); i += size) { if (i != 0) { write("+ "); } int nextSize = MAX_LINE_LENGTH - lineLength - 2; if (nextSize <= 0) { writeLn(); nextSize = MAX_LINE_LENGTH - lineLength - 2; } int end = Math.min(i + nextSize, string.length()); // TODO(CH): fails in normal usage - output ok though // assert lineLength + (end - i) + 2 < MAX_LINE_LENGTH; write("\""); write(string.substring(i, end)); write("\""); size = nextSize; } return ""; } else if (!Character.isAlphabetic(firstCharacter) && firstCharacter != '+') { return m; } if (!lineWrapping) { indent(LINE_WRAP_INDENTS); } lineWrapping = true; lineLength = 0; write(LN); writeIndent(); return m; } private void writeIndent() throws IOException { lineLength += indentSize(); for (int i = 0; i < indent; i++) { writer.write(IDENT_STRING); } } private int indentSize() { return IDENT_STRING.length() * indent; } private static class TrimTrailingSpaceWriter extends Writer { private final Writer delegate; private final StringBuilder buffer = new StringBuilder(); public TrimTrailingSpaceWriter(Writer delegate) { this.delegate = delegate; } @Override public void close() throws IOException { this.delegate.close(); } @Override public void flush() throws IOException { this.delegate.flush(); } @Override public void write(char[] cbuf, int off, int len) throws IOException { buffer.append(cbuf, off, len); int newLinePoint = buffer.indexOf(LN); if (newLinePoint != -1) { String lhs = trimTrailing(buffer.substring(0, newLinePoint)); delegate.write(lhs); delegate.write(LN); buffer.delete(0, newLinePoint + 1); } } private static String trimTrailing(String s) { int cut = 0; for (int i = s.length() - 1; i >= 0; i--) { if (Character.isWhitespace(s.charAt(i))) { cut++; } else { break; } } if (cut > 0) { return s.substring(0, s.length() - cut); } return s; } } } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/transform/FixWarningsVisitor.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/transform/FixWarningsVisitor.ja0000644000000000000000000001130612445312576031044 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.transform; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import static javax.lang.model.element.Modifier.*; import java.io.*; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; public class FixWarningsVisitor extends CodeElementScanner { private final Set symbolsUsed = new HashSet<>(); private final ProcessingEnvironment processingEnv; private final DeclaredType unusedAnnotation; private final DeclaredType overrideType; public FixWarningsVisitor(ProcessingEnvironment processingEnv, DeclaredType unusedAnnotation, DeclaredType overrideType) { this.processingEnv = processingEnv; this.unusedAnnotation = unusedAnnotation; this.overrideType = overrideType; } @Override public Void visitType(CodeTypeElement e, Void p) { List superTypes = ElementUtils.getSuperTypes(e); for (TypeElement type : superTypes) { String qualifiedName = ElementUtils.getQualifiedName(type); if (qualifiedName.equals(Serializable.class.getCanonicalName())) { if (!e.containsField("serialVersionUID")) { e.add(new CodeVariableElement(modifiers(PRIVATE, STATIC, FINAL), ElementUtils.getType(processingEnv, long.class), "serialVersionUID", "1L")); } break; } } return super.visitType(e, p); } @Override public Void visitExecutable(CodeExecutableElement e, Void p) { if (e.getParameters().isEmpty()) { return null; } else if (e.getModifiers().contains(Modifier.ABSTRACT)) { return null; } else if (containsOverride(e)) { return null; } symbolsUsed.clear(); super.visitExecutable(e, p); for (VariableElement parameter : e.getParameters()) { if (!symbolsUsed.contains(parameter.getSimpleName().toString())) { e.getAnnotationMirrors().add(createUnusedAnnotationMirror()); break; } } return null; } private boolean containsOverride(CodeExecutableElement e) { for (AnnotationMirror mirror : e.getAnnotationMirrors()) { if (ElementUtils.typeEquals(overrideType, mirror.getAnnotationType())) { return true; } } return false; } private CodeAnnotationMirror createUnusedAnnotationMirror() { CodeAnnotationMirror mirror = new CodeAnnotationMirror(unusedAnnotation); mirror.setElementValue(mirror.findExecutableElement("value"), new CodeAnnotationValue("unused")); return mirror; } @Override public void visitTree(CodeTree e, Void p, Element enclosingElement) { if (e.getString() != null) { computeSymbols(e.getString()); } super.visitTree(e, p, enclosingElement); } private void computeSymbols(String s) { // TODO there should not be any need for a StringTokenizer if we have a real AST for // method bodies. Also the current solution is not perfect. What if one token // is spread across multiple CodeTree instances? But for now that works. StringTokenizer tokenizer = new StringTokenizer(s, ".= :,()[];{}\"\"'' ", false); while (tokenizer.hasMoreElements()) { String token = tokenizer.nextToken().trim(); if (token.length() > 0) { symbolsUsed.add(token); } } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/ElementUtils.java0000644000000000000000000011401412445312576026153 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java; import java.io.*; import java.lang.annotation.*; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror; /** * THIS IS NOT PUBLIC API. */ public class ElementUtils { public static TypeMirror getType(ProcessingEnvironment processingEnv, Class element) { if (element.isArray()) { return processingEnv.getTypeUtils().getArrayType(getType(processingEnv, element.getComponentType())); } if (element.isPrimitive()) { if (element == void.class) { return processingEnv.getTypeUtils().getNoType(TypeKind.VOID); } TypeKind typeKind; if (element == boolean.class) { typeKind = TypeKind.BOOLEAN; } else if (element == byte.class) { typeKind = TypeKind.BYTE; } else if (element == short.class) { typeKind = TypeKind.SHORT; } else if (element == char.class) { typeKind = TypeKind.CHAR; } else if (element == int.class) { typeKind = TypeKind.INT; } else if (element == long.class) { typeKind = TypeKind.LONG; } else if (element == float.class) { typeKind = TypeKind.FLOAT; } else if (element == double.class) { typeKind = TypeKind.DOUBLE; } else { assert false; return null; } return processingEnv.getTypeUtils().getPrimitiveType(typeKind); } else { TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(element.getCanonicalName()); if (typeElement == null) { return null; } return typeElement.asType(); } } public static ExecutableElement findExecutableElement(DeclaredType type, String name) { List elements = ElementFilter.methodsIn(type.asElement().getEnclosedElements()); for (ExecutableElement executableElement : elements) { if (executableElement.getSimpleName().toString().equals(name)) { return executableElement; } } return null; } public static boolean needsCastTo(TypeMirror sourceType, TypeMirror targetType) { if (typeEquals(sourceType, targetType)) { return false; } else if (isObject(targetType)) { return false; } else if (isVoid(targetType)) { return false; } else if (isAssignable(sourceType, targetType)) { return false; } return true; } public static String createReferenceName(ExecutableElement method) { StringBuilder b = new StringBuilder(); b.append(method.getSimpleName().toString()); b.append("("); String sep = ""; for (VariableElement parameter : method.getParameters()) { b.append(sep); b.append(ElementUtils.getSimpleName(parameter.asType())); sep = ", "; } b.append(")"); return b.toString(); } public static VariableElement findVariableElement(DeclaredType type, String name) { List elements = ElementFilter.fieldsIn(type.asElement().getEnclosedElements()); for (VariableElement variableElement : elements) { if (variableElement.getSimpleName().toString().equals(name)) { return variableElement; } } return null; } public static TypeMirror boxType(ProcessorContext context, TypeMirror primitiveType) { TypeMirror boxedType = primitiveType; if (boxedType.getKind().isPrimitive()) { boxedType = context.getEnvironment().getTypeUtils().boxedClass((PrimitiveType) boxedType).asType(); } return boxedType; } public static DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) { return new DeclaredCodeTypeMirror(typeElem, Arrays.asList(typeArgs)); } public static List collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element, Class annotationClass) { List result = new ArrayList<>(); if (markerAnnotation != null) { result.addAll(ElementUtils.getAnnotationValueList(AnnotationMirror.class, markerAnnotation, elementName)); } AnnotationMirror explicit = ElementUtils.findAnnotationMirror(context.getEnvironment(), element, annotationClass); if (explicit != null) { result.add(explicit); } return result; } public static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror[] types) { if (types.length == 0) { return context.getType(Object.class); } TypeMirror prev = types[0]; for (int i = 1; i < types.length; i++) { prev = getCommonSuperType(context, prev, types[i]); } return prev; } private static TypeMirror getCommonSuperType(ProcessorContext context, TypeMirror type1, TypeMirror type2) { if (typeEquals(type1, type2)) { return type1; } TypeElement element1 = fromTypeMirror(type1); TypeElement element2 = fromTypeMirror(type2); if (element1 == null || element2 == null) { return context.getType(Object.class); } List element1Types = getDirectSuperTypes(element1); element1Types.add(0, element1); List element2Types = getDirectSuperTypes(element2); element2Types.add(0, element2); for (TypeElement superType1 : element1Types) { for (TypeElement superType2 : element2Types) { if (typeEquals(superType1.asType(), superType2.asType())) { return superType2.asType(); } } } return context.getType(Object.class); } public static String getReadableSignature(ExecutableElement method) { // TODO toString does not guarantee a good signature return method.toString(); } public static boolean hasError(TypeMirror mirror) { switch (mirror.getKind()) { case BOOLEAN: case BYTE: case CHAR: case DOUBLE: case FLOAT: case INT: case SHORT: case LONG: case DECLARED: case VOID: case TYPEVAR: return false; case ARRAY: return hasError(((ArrayType) mirror).getComponentType()); case ERROR: return true; default: throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); } } public static boolean isSubtype(TypeMirror type1, TypeMirror type2) { if (type1 instanceof CodeTypeMirror || type2 instanceof CodeTypeMirror) { throw new UnsupportedOperationException(); } return ProcessorContext.getInstance().getEnvironment().getTypeUtils().isSubtype(type1, type2); } public static boolean isAssignable(TypeMirror from, TypeMirror to) { ProcessorContext context = ProcessorContext.getInstance(); if (!(from instanceof CodeTypeMirror) && !(to instanceof CodeTypeMirror)) { return context.getEnvironment().getTypeUtils().isAssignable(context.reloadType(from), context.reloadType(to)); } else { return isAssignableImpl(from, to); } } private static boolean isAssignableImpl(TypeMirror from, TypeMirror to) { // JLS 5.1.1 identity conversion if (ElementUtils.typeEquals(from, to)) { return true; } if (isObject(to)) { return true; } // JLS 5.1.2 widening primitives if (ElementUtils.isPrimitive(from) && ElementUtils.isPrimitive(to)) { TypeKind fromKind = from.getKind(); TypeKind toKind = to.getKind(); switch (fromKind) { case BYTE: switch (toKind) { case SHORT: case INT: case LONG: case FLOAT: case DOUBLE: return true; } break; case SHORT: switch (toKind) { case INT: case LONG: case FLOAT: case DOUBLE: return true; } break; case CHAR: switch (toKind) { case INT: case LONG: case FLOAT: case DOUBLE: return true; } break; case INT: switch (toKind) { case LONG: case FLOAT: case DOUBLE: return true; } break; case LONG: switch (toKind) { case FLOAT: case DOUBLE: return true; } break; case FLOAT: switch (toKind) { case DOUBLE: return true; } break; } return false; } else if (ElementUtils.isPrimitive(from) || ElementUtils.isPrimitive(to)) { return false; } if (from instanceof ArrayType && to instanceof ArrayType) { return isAssignable(((ArrayType) from).getComponentType(), ((ArrayType) to).getComponentType()); } if (from instanceof ArrayType || to instanceof ArrayType) { return false; } TypeElement fromType = ElementUtils.fromTypeMirror(from); TypeElement toType = ElementUtils.fromTypeMirror(to); if (fromType == null || toType == null) { return false; } // JLS 5.1.6 narrowing reference conversion List superTypes = ElementUtils.getSuperTypes(fromType); for (TypeElement superType : superTypes) { if (ElementUtils.typeEquals(superType.asType(), to)) { return true; } } // TODO more spec return false; } public static Set modifiers(Modifier... modifier) { return new LinkedHashSet<>(Arrays.asList(modifier)); } public static String getTypeId(TypeMirror mirror) { switch (mirror.getKind()) { case BOOLEAN: return "Boolean"; case BYTE: return "Byte"; case CHAR: return "Char"; case DOUBLE: return "Double"; case FLOAT: return "Float"; case SHORT: return "Short"; case INT: return "Int"; case LONG: return "Long"; case DECLARED: return fixECJBinaryNameIssue(((DeclaredType) mirror).asElement().getSimpleName().toString()); case ARRAY: return getTypeId(((ArrayType) mirror).getComponentType()) + "Array"; case VOID: return "Void"; case WILDCARD: StringBuilder b = new StringBuilder(); WildcardType type = (WildcardType) mirror; if (type.getExtendsBound() != null) { b.append("Extends").append(getTypeId(type.getExtendsBound())); } else if (type.getSuperBound() != null) { b.append("Super").append(getTypeId(type.getExtendsBound())); } return b.toString(); case TYPEVAR: return "Any"; case ERROR: throw new CompileErrorException("Type error " + mirror); default: throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); } } public static String getSimpleName(TypeElement element) { return getSimpleName(element.asType()); } public static String getSimpleName(TypeMirror mirror) { switch (mirror.getKind()) { case BOOLEAN: return "boolean"; case BYTE: return "byte"; case CHAR: return "char"; case DOUBLE: return "double"; case FLOAT: return "float"; case SHORT: return "short"; case INT: return "int"; case LONG: return "long"; case DECLARED: return getDeclaredName((DeclaredType) mirror, true); case ARRAY: return getSimpleName(((ArrayType) mirror).getComponentType()) + "[]"; case VOID: return "void"; case WILDCARD: return getWildcardName((WildcardType) mirror); case TYPEVAR: return "?"; case ERROR: throw new CompileErrorException("Type error " + mirror); default: throw new RuntimeException("Unknown type specified " + mirror.getKind() + " mirror: " + mirror); } } private static String getWildcardName(WildcardType type) { StringBuilder b = new StringBuilder(); if (type.getExtendsBound() != null) { b.append("? extends ").append(getSimpleName(type.getExtendsBound())); } else if (type.getSuperBound() != null) { b.append("? super ").append(getSimpleName(type.getExtendsBound())); } return b.toString(); } public static String getDeclaredName(DeclaredType element, boolean includeTypeVariables) { String simpleName = fixECJBinaryNameIssue(element.asElement().getSimpleName().toString()); if (!includeTypeVariables || element.getTypeArguments().size() == 0) { return simpleName; } StringBuilder b = new StringBuilder(simpleName); b.append("<"); if (element.getTypeArguments().size() > 0) { for (int i = 0; i < element.getTypeArguments().size(); i++) { b.append(getSimpleName(element.getTypeArguments().get(i))); if (i < element.getTypeArguments().size() - 1) { b.append(", "); } } } b.append(">"); return b.toString(); } public static String fixECJBinaryNameIssue(String name) { if (name.contains("$")) { int lastIndex = name.lastIndexOf('$'); return name.substring(lastIndex + 1, name.length()); } return name; } public static String getQualifiedName(TypeElement element) { String qualifiedName = element.getQualifiedName().toString(); if (qualifiedName.contains("$")) { /* * If a class gets loaded in its binary form by the ECJ compiler it fails to produce the * proper canonical class name. It leaves the $ in the qualified name of the class. So * one instance of a TypeElement may be loaded in binary and one in source form. The * current type comparison in #typeEquals compares by the qualified name so the * qualified name must match. This is basically a hack to fix the returned qualified * name of eclipse. */ qualifiedName = qualifiedName.replace('$', '.'); } return qualifiedName; } public static String getQualifiedName(TypeMirror mirror) { switch (mirror.getKind()) { case BOOLEAN: return "boolean"; case BYTE: return "byte"; case CHAR: return "char"; case DOUBLE: return "double"; case SHORT: return "short"; case FLOAT: return "float"; case INT: return "int"; case LONG: return "long"; case DECLARED: return getQualifiedName(fromTypeMirror(mirror)); case ARRAY: return getQualifiedName(((ArrayType) mirror).getComponentType()); case VOID: return "void"; case TYPEVAR: return getSimpleName(mirror); case ERROR: throw new CompileErrorException("Type error " + mirror); case EXECUTABLE: return ((ExecutableType) mirror).toString(); case NONE: return "$none"; default: throw new RuntimeException("Unknown type specified " + mirror + " mirror: " + mirror); } } public static boolean isVoid(TypeMirror mirror) { return mirror != null && mirror.getKind() == TypeKind.VOID; } public static boolean isPrimitive(TypeMirror mirror) { return mirror != null && mirror.getKind().isPrimitive(); } public static List getQualifiedSuperTypeNames(TypeElement element) { List types = getSuperTypes(element); List qualifiedNames = new ArrayList<>(); for (TypeElement type : types) { qualifiedNames.add(getQualifiedName(type)); } return qualifiedNames; } public static List getDeclaredTypes(TypeElement element) { return ElementFilter.typesIn(element.getEnclosedElements()); } public static boolean isEnclosedIn(Element enclosedIn, Element element) { if (element == null) { return false; } else if (typeEquals(enclosedIn.asType(), element.asType())) { return true; } else { return isEnclosedIn(enclosedIn, element.getEnclosingElement()); } } public static TypeElement findRootEnclosingType(Element element) { List elements = getElementHierarchy(element); for (int i = elements.size() - 1; i >= 0; i--) { if (elements.get(i).getKind().isClass()) { return (TypeElement) elements.get(i); } } return null; } public static List getElementHierarchy(Element e) { List elements = new ArrayList<>(); elements.add(e); Element enclosing = e.getEnclosingElement(); while (enclosing != null && enclosing.getKind() != ElementKind.PACKAGE) { elements.add(enclosing); enclosing = enclosing.getEnclosingElement(); } if (enclosing != null) { elements.add(enclosing); } return elements; } public static TypeElement findNearestEnclosingType(Element element) { List elements = getElementHierarchy(element); for (Element e : elements) { if (e.getKind().isClass()) { return (TypeElement) e; } } return null; } public static List getDirectSuperTypes(TypeElement element) { List types = new ArrayList<>(); TypeElement superElement = getSuperType(element); if (superElement != null) { types.add(superElement); types.addAll(getDirectSuperTypes(superElement)); } return types; } public static List getAssignableTypes(ProcessorContext context, TypeMirror type) { if (isPrimitive(type)) { return Arrays.asList(type, boxType(context, type), context.getType(Object.class)); } else if (type.getKind() == TypeKind.ARRAY) { return Arrays.asList(type, context.getType(Object.class)); } else if (type.getKind() == TypeKind.DECLARED) { DeclaredType declaredType = (DeclaredType) type; TypeElement typeElement = fromTypeMirror(declaredType); List types = getSuperTypes(typeElement); List mirrors = new ArrayList<>(types.size()); mirrors.add(type); for (TypeElement superTypeElement : types) { mirrors.add(superTypeElement.asType()); } if (typeElement.getKind().isInterface()) { mirrors.add(getType(context.getEnvironment(), Object.class)); } return mirrors; } else { return Collections.emptyList(); } } /** * Gets the element representing the {@linkplain TypeElement#getSuperclass() super class} of a * given type element. */ public static TypeElement getSuperType(TypeElement element) { if (element.getSuperclass() != null) { return fromTypeMirror(element.getSuperclass()); } return null; } public static List getSuperTypes(TypeElement element) { List types = new ArrayList<>(); List superTypes = null; List superInterfaces = null; TypeElement superElement = getSuperType(element); if (superElement != null) { types.add(superElement); superTypes = getSuperTypes(superElement); } for (TypeMirror interfaceMirror : element.getInterfaces()) { TypeElement interfaceElement = fromTypeMirror(interfaceMirror); if (interfaceElement != null) { types.add(interfaceElement); if (superInterfaces == null) { superInterfaces = getSuperTypes(interfaceElement); } else { superInterfaces.addAll(getSuperTypes(interfaceElement)); } } } if (superTypes != null) { types.addAll(superTypes); } if (superInterfaces != null) { types.addAll(superInterfaces); } return types; } public static String getPackageName(TypeElement element) { return findPackageElement(element).getQualifiedName().toString(); } public static String getEnclosedQualifiedName(DeclaredType mirror) { Element e = ((TypeElement) mirror.asElement()).getEnclosingElement(); if (e.getKind() == ElementKind.PACKAGE) { return ((PackageElement) e).getQualifiedName().toString(); } else if (e.getKind().isInterface() || e.getKind().isClass()) { return getQualifiedName((TypeElement) e); } else { return null; } } public static String getPackageName(TypeMirror mirror) { switch (mirror.getKind()) { case BOOLEAN: case BYTE: case CHAR: case DOUBLE: case FLOAT: case SHORT: case INT: case LONG: case VOID: case TYPEVAR: return null; case DECLARED: PackageElement pack = findPackageElement(fromTypeMirror(mirror)); if (pack == null) { throw new IllegalArgumentException("No package element found for declared type " + getSimpleName(mirror)); } return pack.getQualifiedName().toString(); case ARRAY: return getSimpleName(((ArrayType) mirror).getComponentType()); default: throw new RuntimeException("Unknown type specified " + mirror.getKind()); } } public static String createConstantName(String simpleName) { // TODO use camel case to produce underscores. return simpleName.toString().toUpperCase(); } public static TypeElement fromTypeMirror(TypeMirror mirror) { switch (mirror.getKind()) { case DECLARED: return (TypeElement) ((DeclaredType) mirror).asElement(); case ARRAY: return fromTypeMirror(((ArrayType) mirror).getComponentType()); default: return null; } } @SuppressWarnings("unchecked") public static List getAnnotationValueList(Class expectedListType, AnnotationMirror mirror, String name) { List values = getAnnotationValue(List.class, mirror, name); List result = new ArrayList<>(); if (values != null) { for (AnnotationValue value : values) { T annotationValue = resolveAnnotationValue(expectedListType, value); if (annotationValue != null) { result.add(annotationValue); } } } return result; } public static T getAnnotationValue(Class expectedType, AnnotationMirror mirror, String name) { return resolveAnnotationValue(expectedType, getAnnotationValue(mirror, name)); } @SuppressWarnings({"unchecked"}) private static T resolveAnnotationValue(Class expectedType, AnnotationValue value) { if (value == null) { return null; } Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null); if (unboxedValue != null) { if (expectedType == TypeMirror.class && unboxedValue instanceof String) { return null; } if (!expectedType.isAssignableFrom(unboxedValue.getClass())) { throw new ClassCastException(unboxedValue.getClass().getName() + " not assignable from " + expectedType.getName()); } } return (T) unboxedValue; } public static AnnotationValue getAnnotationValue(AnnotationMirror mirror, String name) { ExecutableElement valueMethod = null; for (ExecutableElement method : ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) { if (method.getSimpleName().toString().equals(name)) { valueMethod = method; break; } } if (valueMethod == null) { return null; } AnnotationValue value = mirror.getElementValues().get(valueMethod); if (value == null) { value = valueMethod.getDefaultValue(); } return value; } private static class AnnotationValueVisitorImpl extends AbstractAnnotationValueVisitor7 { @Override public Object visitBoolean(boolean b, Void p) { return Boolean.valueOf(b); } @Override public Object visitByte(byte b, Void p) { return Byte.valueOf(b); } @Override public Object visitChar(char c, Void p) { return c; } @Override public Object visitDouble(double d, Void p) { return d; } @Override public Object visitFloat(float f, Void p) { return f; } @Override public Object visitInt(int i, Void p) { return i; } @Override public Object visitLong(long i, Void p) { return i; } @Override public Object visitShort(short s, Void p) { return s; } @Override public Object visitString(String s, Void p) { return s; } @Override public Object visitType(TypeMirror t, Void p) { return t; } @Override public Object visitEnumConstant(VariableElement c, Void p) { return c; } @Override public Object visitAnnotation(AnnotationMirror a, Void p) { return a; } @Override public Object visitArray(List vals, Void p) { return vals; } } public static String printException(Throwable e) { StringWriter string = new StringWriter(); PrintWriter writer = new PrintWriter(string); e.printStackTrace(writer); writer.flush(); return e.getMessage() + "\r\n" + string.toString(); } public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, Element element, Class annotationClass) { return findAnnotationMirror(processingEnv, element.getAnnotationMirrors(), annotationClass); } public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, List mirrors, Class annotationClass) { TypeElement expectedAnnotationType = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName()); return findAnnotationMirror(mirrors, expectedAnnotationType); } public static AnnotationMirror findAnnotationMirror(List mirrors, TypeElement expectedAnnotationType) { for (AnnotationMirror mirror : mirrors) { DeclaredType annotationType = mirror.getAnnotationType(); TypeElement actualAnnotationType = (TypeElement) annotationType.asElement(); if (actualAnnotationType.equals(expectedAnnotationType)) { return mirror; } } return null; } public static PackageElement findPackageElement(Element type) { List hierarchy = getElementHierarchy(type); for (Element element : hierarchy) { if (element.getKind() == ElementKind.PACKAGE) { return (PackageElement) element; } } return null; } public static String firstLetterUpperCase(String name) { if (name == null || name.isEmpty()) { return name; } return Character.toUpperCase(name.charAt(0)) + name.substring(1, name.length()); } public static String firstLetterLowerCase(String name) { if (name == null || name.isEmpty()) { return name; } return Character.toLowerCase(name.charAt(0)) + name.substring(1, name.length()); } private static ExecutableElement getDeclaredMethod(TypeElement element, String name, TypeMirror[] params) { List methods = ElementFilter.methodsIn(element.getEnclosedElements()); method: for (ExecutableElement method : methods) { if (!method.getSimpleName().toString().equals(name)) { continue; } if (method.getParameters().size() != params.length) { continue; } for (int i = 0; i < params.length; i++) { TypeMirror param1 = params[i]; TypeMirror param2 = method.getParameters().get(i).asType(); if (param1.getKind() != TypeKind.TYPEVAR && param2.getKind() != TypeKind.TYPEVAR) { if (!getQualifiedName(param1).equals(getQualifiedName(param2))) { continue method; } } } return method; } return null; } public static boolean isDeclaredMethodInSuperType(TypeElement element, String name, TypeMirror[] params) { return !getDeclaredMethodsInSuperTypes(element, name, params).isEmpty(); } /** * Gets the methods in the super type hierarchy (excluding interfaces) that are overridden by a * method in a subtype. * * @param declaringElement the subtype element declaring the method * @param name the name of the method * @param params the signature of the method */ public static List getDeclaredMethodsInSuperTypes(TypeElement declaringElement, String name, TypeMirror... params) { List superMethods = new ArrayList<>(); List superElements = getSuperTypes(declaringElement); for (TypeElement superElement : superElements) { ExecutableElement superMethod = getDeclaredMethod(superElement, name, params); if (superMethod != null) { superMethods.add(superMethod); } } return superMethods; } public static boolean typeEquals(TypeMirror type1, TypeMirror type2) { if (type1 == type2) { return true; } else if (type1 == null || type2 == null) { return false; } else { if (type1.getKind() == type2.getKind()) { return getUniqueIdentifier(type1).equals(getUniqueIdentifier(type2)); } else { return false; } } } public static String getUniqueIdentifier(TypeMirror typeMirror) { if (typeMirror.getKind() == TypeKind.ARRAY) { return getUniqueIdentifier(((ArrayType) typeMirror).getComponentType()) + "[]"; } else { return getQualifiedName(typeMirror); } } public static int compareByTypeHierarchy(TypeMirror t1, TypeMirror t2) { if (typeEquals(t1, t2)) { return 0; } Set t1SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t1))); if (t1SuperSet.contains(getQualifiedName(t2))) { return -1; } Set t2SuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(t2))); if (t2SuperSet.contains(getQualifiedName(t1))) { return 1; } return 0; } public static boolean canThrowType(List thrownTypes, TypeMirror exceptionType) { if (ElementUtils.containsType(thrownTypes, exceptionType)) { return true; } if (isRuntimeException(exceptionType)) { return true; } // search for any super types TypeElement exceptionTypeElement = fromTypeMirror(exceptionType); List superTypes = getSuperTypes(exceptionTypeElement); for (TypeElement typeElement : superTypes) { if (ElementUtils.containsType(thrownTypes, typeElement.asType())) { return true; } } return false; } public static Modifier getVisibility(Set modifier) { for (Modifier mod : modifier) { if (mod == Modifier.PUBLIC || mod == Modifier.PRIVATE || mod == Modifier.PROTECTED) { return mod; } } return null; } private static boolean isRuntimeException(TypeMirror type) { Set typeSuperSet = new HashSet<>(getQualifiedSuperTypeNames(fromTypeMirror(type))); String typeName = getQualifiedName(type); if (!typeSuperSet.contains(Throwable.class.getCanonicalName()) && !typeName.equals(Throwable.class.getCanonicalName())) { throw new IllegalArgumentException("Given type does not extend Throwable."); } return typeSuperSet.contains(RuntimeException.class.getCanonicalName()) || typeName.equals(RuntimeException.class.getCanonicalName()); } private static boolean containsType(Collection collection, TypeMirror type) { for (TypeMirror otherTypeMirror : collection) { if (typeEquals(otherTypeMirror, type)) { return true; } } return false; } public static boolean isTopLevelClass(TypeMirror importType) { TypeElement type = fromTypeMirror(importType); if (type != null && type.getEnclosingElement() != null) { return !type.getEnclosingElement().getKind().isClass(); } return true; } public static boolean isObject(TypeMirror actualType) { return actualType.getKind() == TypeKind.DECLARED && getQualifiedName(actualType).equals("java.lang.Object"); } public static TypeMirror fillInGenericWildcards(TypeMirror type) { if (type.getKind() != TypeKind.DECLARED) { return type; } DeclaredType declaredType = (DeclaredType) type; TypeElement element = (TypeElement) declaredType.asElement(); if (element == null) { return type; } int typeParameters = element.getTypeParameters().size(); if (typeParameters > 0 && declaredType.getTypeArguments().size() != typeParameters) { return ProcessorContext.getInstance().getEnvironment().getTypeUtils().erasure(type); } return type; } public static TypeMirror eraseGenericTypes(TypeMirror type) { if (type.getKind() != TypeKind.DECLARED) { return type; } DeclaredType declaredType = (DeclaredType) type; if (declaredType.getTypeArguments().size() == 0) { return type; } return new DeclaredCodeTypeMirror((TypeElement) declaredType.asElement()); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/compiler/0000755000000000000000000000000012460760144024502 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/compiler/AbstractCompiler.java0000644000000000000000000000555712445312576030624 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.compiler; import java.lang.reflect.*; public abstract class AbstractCompiler implements Compiler { protected static Object method(Object o, String methodName) throws Exception { Method method = o.getClass().getMethod(methodName); method.setAccessible(true); return method.invoke(o); } protected static Object method(Object o, String methodName, Class[] paramTypes, Object... values) throws Exception { Method method = o.getClass().getMethod(methodName, paramTypes); method.setAccessible(true); return method.invoke(o, values); } protected static Object field(Object o, String fieldName) throws Exception { if (o == null) { return null; } Class clazz = o.getClass(); Field field = null; try { field = clazz.getField(fieldName); } catch (NoSuchFieldException e) { while (clazz != null) { try { field = clazz.getDeclaredField(fieldName); break; } catch (NoSuchFieldException e1) { clazz = clazz.getSuperclass(); } } if (field == null) { throw e; } } field.setAccessible(true); return field.get(o); } protected static String parseHeader(String content) { int index = content.indexOf("/*"); if (index == -1) { return null; } if (!content.substring(0, index).trim().equals("")) { // just whitespace before return null; } int endIndex = content.indexOf("*/", index); if (endIndex == -1) { return null; } return content.substring(index, endIndex + 2); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/compiler/Compiler.java0000644000000000000000000000306212445312576027125 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.compiler; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; public interface Compiler { String getMethodBody(ProcessingEnvironment env, ExecutableElement method); String getHeaderComment(ProcessingEnvironment env, Element type); List getEnclosedElementsInDeclarationOrder(TypeElement type); List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type); } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/compiler/JDTCompiler.java0000644000000000000000000003325312445312576027474 0ustar /* * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.compiler; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; import com.oracle.truffle.dsl.processor.java.*; public class JDTCompiler extends AbstractCompiler { public static boolean isValidElement(Element currentElement) { try { Class elementClass = Class.forName("org.eclipse.jdt.internal.compiler.apt.model.ElementImpl"); return elementClass.isAssignableFrom(currentElement.getClass()); } catch (ClassNotFoundException e) { return false; } } public List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type) { return sortBySourceOrder(new ArrayList<>(environment.getElementUtils().getAllMembers(type))); } public List getEnclosedElementsInDeclarationOrder(TypeElement type) { return sortBySourceOrder(new ArrayList<>(type.getEnclosedElements())); } private static List sortBySourceOrder(List elements) { Map> groupedByEnclosing = new HashMap<>(); for (Element element : elements) { Element enclosing = element.getEnclosingElement(); List grouped = groupedByEnclosing.get(enclosing); if (grouped == null) { grouped = new ArrayList<>(); groupedByEnclosing.put((TypeElement) enclosing, grouped); } grouped.add(element); } for (TypeElement enclosing : groupedByEnclosing.keySet()) { Collections.sort(groupedByEnclosing.get(enclosing), createSourceOrderComparator(enclosing)); } if (groupedByEnclosing.size() == 1) { return groupedByEnclosing.get(groupedByEnclosing.keySet().iterator().next()); } else { List enclosingTypes = new ArrayList<>(groupedByEnclosing.keySet()); Collections.sort(enclosingTypes, new Comparator() { public int compare(TypeElement o1, TypeElement o2) { if (ElementUtils.isSubtype(o1.asType(), o2.asType())) { return 1; } else { return -1; } } }); List sourceOrderElements = new ArrayList<>(); for (TypeElement typeElement : enclosingTypes) { sourceOrderElements.addAll(groupedByEnclosing.get(typeElement)); } return sourceOrderElements; } } private static Comparator createSourceOrderComparator(final TypeElement enclosing) { Comparator comparator = new Comparator() { final List declarationOrder = lookupDeclarationOrder(enclosing); public int compare(Element o1, Element o2) { try { Element enclosing1Element = o1.getEnclosingElement(); Element enclosing2Element = o2.getEnclosingElement(); if (!ElementUtils.typeEquals(enclosing1Element.asType(), enclosing2Element.asType())) { throw new AssertionError(); } Object o1Binding = field(o1, "_binding"); Object o2Binding = field(o2, "_binding"); int i1 = declarationOrder.indexOf(o1Binding); int i2 = declarationOrder.indexOf(o2Binding); if (i1 == -1 || i2 == -1) { return 0; } return i1 - i2; } catch (Exception e) { throw new RuntimeException(e); } } }; return comparator; } private static List lookupDeclarationOrder(TypeElement type) { List declarationOrder; try { Object binding = field(type, "_binding"); Class sourceTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding"); Class binaryTypeBinding = Class.forName("org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding"); declarationOrder = null; if (sourceTypeBinding.isAssignableFrom(binding.getClass())) { declarationOrder = findSourceTypeOrder(binding); } else if (binaryTypeBinding.isAssignableFrom(binding.getClass())) { declarationOrder = findBinaryTypeOrder(binding); } } catch (Exception e) { throw new RuntimeException(e); } return declarationOrder; } private static List findBinaryTypeOrder(Object binding) throws Exception { Object binaryType = lookupBinaryType(binding); final Object[] sortedMethods = (Object[]) method(binaryType, "getMethods"); List sortedElements = new ArrayList<>(); if (sortedMethods != null) { sortedElements.addAll(Arrays.asList(sortedMethods)); } final Object[] sortedFields = (Object[]) method(binaryType, "getFields"); if (sortedFields != null) { sortedElements.addAll(Arrays.asList(sortedFields)); } final Object[] sortedTypes = (Object[]) method(binaryType, "getMemberTypes", new Class[0]); if (sortedTypes != null) { sortedElements.addAll(Arrays.asList(sortedTypes)); } Collections.sort(sortedElements, new Comparator() { public int compare(Object o1, Object o2) { try { int structOffset1 = (int) field(o1, "structOffset"); int structOffset2 = (int) field(o2, "structOffset"); return structOffset1 - structOffset2; } catch (Exception e) { throw new RuntimeException(e); } } }); Class binaryMethod = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryMethod"); Class binaryField = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryField"); Class nestedType = Class.forName("org.eclipse.jdt.internal.compiler.env.IBinaryNestedType"); List bindings = new ArrayList<>(); for (Object sortedElement : sortedElements) { Class elementClass = sortedElement.getClass(); if (binaryMethod.isAssignableFrom(elementClass)) { char[] selector = (char[]) method(sortedElement, "getSelector"); Object[] foundBindings = (Object[]) method(binding, "getMethods", new Class[]{char[].class}, selector); if (foundBindings == null || foundBindings.length == 0) { continue; } else if (foundBindings.length == 1) { bindings.add(foundBindings[0]); } else { char[] idescriptor = (char[]) method(sortedElement, "getMethodDescriptor"); for (Object foundBinding : foundBindings) { char[] descriptor = (char[]) method(foundBinding, "signature"); if (descriptor == null && idescriptor == null || Arrays.equals(descriptor, idescriptor)) { bindings.add(foundBinding); break; } } } } else if (binaryField.isAssignableFrom(elementClass)) { char[] selector = (char[]) method(sortedElement, "getName"); Object foundField = method(binding, "getField", new Class[]{char[].class, boolean.class}, selector, true); if (foundField != null) { bindings.add(foundField); } } else if (nestedType.isAssignableFrom(elementClass)) { char[] selector = (char[]) method(sortedElement, "getSourceName"); Object foundType = method(binding, "getMemberType", new Class[]{char[].class}, selector); if (foundType != null) { bindings.add(foundType); } } else { throw new AssertionError("Unexpected encountered type " + elementClass); } } return bindings; } private static Object lookupBinaryType(Object binding) throws Exception { Object lookupEnvironment = field(binding, "environment"); Object compoundClassName = field(binding, "compoundName"); Object nameEnvironment = field(lookupEnvironment, "nameEnvironment"); Object nameEnvironmentAnswer = method(nameEnvironment, "findType", new Class[]{char[][].class}, compoundClassName); Object binaryType = method(nameEnvironmentAnswer, "getBinaryType", new Class[0]); return binaryType; } private static List findSourceTypeOrder(Object binding) throws Exception { Object referenceContext = field(field(binding, "scope"), "referenceContext"); TreeMap orderedBindings = new TreeMap<>(); collectSourceOrder(orderedBindings, referenceContext, "methods"); collectSourceOrder(orderedBindings, referenceContext, "fields"); collectSourceOrder(orderedBindings, referenceContext, "memberTypes"); return new ArrayList<>(orderedBindings.values()); } private static void collectSourceOrder(TreeMap orderedBindings, Object referenceContext, String fieldName) throws Exception { Object[] declarations = (Object[]) field(referenceContext, fieldName); if (declarations != null) { for (int i = 0; i < declarations.length; i++) { Integer declarationSourceStart = (Integer) field(declarations[i], "declarationSourceStart"); orderedBindings.put(declarationSourceStart, field(declarations[i], "binding")); } } } @Override public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) { try { char[] source = getSource(method); if (source == null) { return null; } /* * AbstractMethodDeclaration decl = * ((MethodBinding)(((ElementImpl)method)._binding)).sourceMethod(); int bodyStart = * decl.bodyStart; int bodyEnd = decl.bodyEnd; */ Object decl = method(field(method, "_binding"), "sourceMethod"); int bodyStart = (int) field(decl, "bodyStart"); int bodyEnd = (int) field(decl, "bodyEnd"); int length = bodyEnd - bodyStart; char[] target = new char[length]; System.arraycopy(source, bodyStart, target, 0, length); return new String(target); } catch (Exception e) { return ElementUtils.printException(e); } } private static char[] getSource(Element element) throws Exception { /* * Binding binding = ((ElementImpl)element)._binding; char[] source = null; if (binding * instanceof MethodBinding) { source = ((MethodBinding) * binding).sourceMethod().compilationResult.getCompilationUnit().getContents(); } else if * (binding instanceof SourceTypeBinding) { source = * ((SourceTypeBinding)binding).scope.referenceContext * .compilationResult.compilationUnit.getContents(); } return source; */ Object binding = field(element, "_binding"); Class methodBindingClass = Class.forName("org.eclipse.jdt.internal.compiler.lookup.MethodBinding"); Class referenceBindingClass = Class.forName("org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding"); char[] source = null; if (methodBindingClass.isAssignableFrom(binding.getClass())) { Object sourceMethod = method(binding, "sourceMethod"); if (sourceMethod == null) { return null; } source = (char[]) method(method(field(sourceMethod, "compilationResult"), "getCompilationUnit"), "getContents"); } else if (referenceBindingClass.isAssignableFrom(binding.getClass())) { source = (char[]) method(field(field(field(field(binding, "scope"), "referenceContext"), "compilationResult"), "compilationUnit"), "getContents"); } return source; } @Override public String getHeaderComment(ProcessingEnvironment env, Element type) { try { char[] source = getSource(type); if (source == null) { return null; } return parseHeader(new String(source)); } catch (Exception e) { return ElementUtils.printException(e); } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/compiler/CompilerFactory.java0000644000000000000000000000345112445312576030457 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.compiler; import javax.lang.model.element.*; public class CompilerFactory { private static Compiler javac; private static Compiler jdt; public static Compiler getCompiler(Element currentElement) { if (JavaCCompiler.isValidElement(currentElement)) { if (javac == null) { javac = new JavaCCompiler(); } return javac; } else if (JDTCompiler.isValidElement(currentElement)) { if (jdt == null) { jdt = new JDTCompiler(); } return jdt; } else { throw new UnsupportedOperationException("Unsupported compiler for element " + currentElement.getClass().getName() + "."); } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/compiler/JavaCCompiler.java0000644000000000000000000001045712445312576030040 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.compiler; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; import com.oracle.truffle.dsl.processor.java.*; public class JavaCCompiler extends AbstractCompiler { public static boolean isValidElement(Element currentElement) { try { Class elementClass = Class.forName("com.sun.tools.javac.code.Symbol"); return elementClass.isAssignableFrom(currentElement.getClass()); } catch (ClassNotFoundException e) { return false; } } public List getEnclosedElementsInDeclarationOrder(TypeElement type) { return type.getEnclosedElements(); } public List getAllMembersInDeclarationOrder(ProcessingEnvironment environment, TypeElement type) { return environment.getElementUtils().getAllMembers(type); } private static final Class[] getTreeAndTopLevelSignature = new Class[]{Element.class, AnnotationMirror.class, AnnotationValue.class}; private static final Class[] getCharContentSignature = new Class[]{boolean.class}; @Override public String getMethodBody(ProcessingEnvironment env, ExecutableElement method) { try { /* * if (false) { Pair treeAndTopLevel = ((JavacElements) * env.getElementUtils()).getTreeAndTopLevel(method, null, null); JCBlock block = * ((JCMethodDecl) treeAndTopLevel.fst).getBody(); int startPos = block.pos; int endPos * = block.endpos; String methodBody = * treeAndTopLevel.snd.getSourceFile().getCharContent(true).subSequence(startPos + 1, * endPos).toString(); return methodBody; } */ Object treeAndTopLevel = getTreeAndTopLevel(env, method); Object block = method(field(treeAndTopLevel, "fst"), "getBody"); int startPos = (int) field(block, "pos"); int endPos = (int) field(block, "endpos"); return getContent(treeAndTopLevel).subSequence(startPos + 1, endPos).toString(); } catch (Exception e) { return ElementUtils.printException(e); } } private static CharSequence getContent(Object treeAndTopLevel) throws Exception { /* * CharSequence content = treeAndTopLevel.snd.getSourceFile().getCharContent(true); */ return (CharSequence) method(method(field(treeAndTopLevel, "snd"), "getSourceFile"), "getCharContent", getCharContentSignature, true); } private static Object getTreeAndTopLevel(ProcessingEnvironment env, Element element) throws Exception { /* * Pair treeAndTopLevel = ((JavacElements) * env.getElementUtils()).getTreeAndTopLevel(method, null, null); */ return method(method(env, "getElementUtils"), "getTreeAndTopLevel", getTreeAndTopLevelSignature, element, null, null); } @Override public String getHeaderComment(ProcessingEnvironment env, Element type) { try { String content = getContent(getTreeAndTopLevel(env, type)).toString(); return parseHeader(content); } catch (Exception e) { return ElementUtils.printException(e); } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/0000755000000000000000000000000012460760144023770 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeAnnotationMirror.java0000644000000000000000000000402512445312576030741 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; public class CodeAnnotationMirror implements AnnotationMirror { private final DeclaredType annotationType; private final Map values = new LinkedHashMap<>(); public CodeAnnotationMirror(DeclaredType annotationType) { this.annotationType = annotationType; } @Override public DeclaredType getAnnotationType() { return annotationType; } @Override public Map getElementValues() { return values; } public void setElementValue(ExecutableElement method, AnnotationValue value) { values.put(method, value); } public ExecutableElement findExecutableElement(String name) { return ElementUtils.findExecutableElement(annotationType, name); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeNames.java0000644000000000000000000000475012445312576026504 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; public abstract class CodeNames { private static Map names = new HashMap<>(); public static Name of(String value) { Name name = names.get(value); if (name == null) { name = new NameImpl(value); names.put(value, name); } return name; } private static class NameImpl implements Name { private final String name; public NameImpl(String name) { this.name = name; } @Override public int length() { return name.length(); } @Override public char charAt(int index) { return name.charAt(index); } @Override public CharSequence subSequence(int start, int end) { return name.subSequence(start, end); } @Override public boolean contentEquals(CharSequence cs) { return name.contentEquals(cs); } @Override public boolean equals(Object obj) { if (obj instanceof Name) { return ((Name) obj).contentEquals(name); } return super.equals(obj); } @Override public int hashCode() { return name.hashCode(); } @Override public String toString() { return name; } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/GeneratedTypeElement.java0000644000000000000000000000267612445312576030725 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; public final class GeneratedTypeElement extends CodeTypeElement { public GeneratedTypeElement(Set modifiers, ElementKind kind, PackageElement packageElement, String simpleName) { super(modifiers, kind, packageElement, simpleName); setEnclosingElement(packageElement); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeTypeElement.java0000644000000000000000000001346212445312576027674 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror; public class CodeTypeElement extends CodeElement implements TypeElement { private final List imports = parentableList(this, new ArrayList()); private final PackageElement packageElement; private final Name simpleName; private final Name packageName; private Name qualifiedName; private final List implementsInterfaces = new ArrayList<>(); private final ElementKind kind; private TypeMirror superClass; private final DeclaredCodeTypeMirror mirror = new DeclaredCodeTypeMirror(this); public CodeTypeElement(Set modifiers, ElementKind kind, PackageElement packageElement, String simpleName) { super(modifiers); this.kind = kind; this.packageElement = packageElement; this.simpleName = CodeNames.of(simpleName); if (this.packageElement != null) { this.packageName = packageElement.getQualifiedName(); } else { this.packageName = CodeNames.of("default"); } this.qualifiedName = createQualifiedName(); } @Override public TypeMirror asType() { return mirror; } @Override public ElementKind getKind() { return kind; } public boolean containsField(String name) { for (VariableElement field : getFields()) { if (field.getSimpleName().toString().equals(name)) { return true; } } return false; } @Override public NestingKind getNestingKind() { return isTopLevelClass() ? NestingKind.TOP_LEVEL : NestingKind.LOCAL; } @Override public Element getEnclosingElement() { if (isTopLevelClass()) { return packageElement; } else { return super.getEnclosingElement(); } } @Override public TypeMirror getSuperclass() { return superClass; } @Override public List getInterfaces() { return implementsInterfaces; } @Override public List getTypeParameters() { return Collections.emptyList(); } public boolean isTopLevelClass() { return super.getEnclosingElement() instanceof CodeCompilationUnit; } private Name createQualifiedName() { TypeElement enclosingType = getEnclosingClass(); if (enclosingType == null) { return CodeNames.of(packageName + "." + simpleName); } else { return CodeNames.of(enclosingType.getQualifiedName() + "." + simpleName); } } @Override public void setEnclosingElement(Element element) { super.setEnclosingElement(element); // update qualified name on container change this.qualifiedName = createQualifiedName(); } public Name getPackageName() { return packageName; } @Override public Name getQualifiedName() { return qualifiedName; } @Override public Name getSimpleName() { return simpleName; } public void setSuperClass(TypeMirror superType) { this.superClass = superType; } public List getImports() { return imports; } public List getImplements() { return implementsInterfaces; } @Override public int hashCode() { return getQualifiedName().hashCode(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } else if (obj instanceof TypeElement) { return getQualifiedName().equals(((TypeElement) obj).getQualifiedName()); } return false; } public List getFields() { return ElementFilter.fieldsIn(getEnclosedElements()); } public ExecutableElement getMethod(String name) { for (Element element : getEnclosedElements()) { if (element.getKind() == ElementKind.METHOD && element.getSimpleName().toString().equals(name)) { return (ExecutableElement) element; } } return null; } public List getMethods() { return ElementFilter.methodsIn(getEnclosedElements()); } public List getInnerClasses() { return ElementFilter.typesIn(getEnclosedElements()); } @Override public String toString() { return getQualifiedName().toString(); } @Override public R accept(ElementVisitor v, P p) { return v.visitType(this, p); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeTypeMirror.java0000644000000000000000000000777612445312576027570 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; public class CodeTypeMirror implements TypeMirror { private final TypeKind kind; public CodeTypeMirror(TypeKind kind) { this.kind = kind; } @Override public TypeKind getKind() { return kind; } @Override public R accept(TypeVisitor v, P p) { throw new UnsupportedOperationException(); } public static class WildcardTypeMirror extends CodeTypeMirror implements WildcardType { private final TypeMirror extendsBounds; private final TypeMirror superBounds; public WildcardTypeMirror(TypeMirror extendsBounds, TypeMirror superBounds) { super(TypeKind.WILDCARD); this.extendsBounds = extendsBounds; this.superBounds = superBounds; } public TypeMirror getExtendsBound() { return extendsBounds; } public TypeMirror getSuperBound() { return superBounds; } } public static class ArrayCodeTypeMirror extends CodeTypeMirror implements ArrayType { private final TypeMirror component; public ArrayCodeTypeMirror(TypeMirror component) { super(TypeKind.ARRAY); this.component = component; } @Override public TypeMirror getComponentType() { return component; } } public static class DeclaredCodeTypeMirror extends CodeTypeMirror implements DeclaredType { private final TypeElement clazz; private final List typeArguments; public DeclaredCodeTypeMirror(TypeElement clazz) { this(clazz, Collections. emptyList()); } public DeclaredCodeTypeMirror(TypeElement clazz, List typeArguments) { super(TypeKind.DECLARED); this.clazz = clazz; this.typeArguments = typeArguments; } @Override public Element asElement() { return clazz; } @Override public TypeMirror getEnclosingType() { return clazz.getEnclosingElement().asType(); } @Override public List getTypeArguments() { return typeArguments; } @Override public String toString() { return clazz.getQualifiedName().toString(); } } public List getAnnotationMirrors() { throw new UnsupportedOperationException(); } /** * @param annotationType */ public A getAnnotation(Class annotationType) { throw new UnsupportedOperationException(); } /** * @param annotationType */ public A[] getAnnotationsByType(Class annotationType) { throw new UnsupportedOperationException(); } } ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeExecutableElement.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeExecutableElement.jav0000644000000000000000000001346712445312576030700 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; public class CodeExecutableElement extends CodeElement implements ExecutableElement { private final List throwables = new ArrayList<>(); private final List parameters = parentableList(this, new ArrayList()); private TypeMirror returnType; private Name name; private CodeTree bodyTree; private String body; private AnnotationValue defaultValue; private boolean varArgs; public CodeExecutableElement(TypeMirror returnType, String name) { super(ElementUtils.modifiers()); this.returnType = returnType; this.name = CodeNames.of(name); } public CodeExecutableElement(Set modifiers, TypeMirror returnType, String name, CodeVariableElement... parameters) { super(modifiers); this.returnType = returnType; this.name = CodeNames.of(name); for (CodeVariableElement codeParameter : parameters) { addParameter(codeParameter); } } /* Support JDK8 langtools. */ public boolean isDefault() { return false; } @Override public List getThrownTypes() { return throwables; } @Override public TypeMirror asType() { return returnType; } @Override public ElementKind getKind() { if (getReturnType() == null) { return ElementKind.CONSTRUCTOR; } else { return ElementKind.METHOD; } } @Override public List getTypeParameters() { return Collections.emptyList(); } public void setVarArgs(boolean varargs) { this.varArgs = varargs; } @Override public boolean isVarArgs() { return varArgs; } public void setDefaultValue(AnnotationValue defaultValue) { this.defaultValue = defaultValue; } @Override public AnnotationValue getDefaultValue() { return defaultValue; } @Override public Name getSimpleName() { return name; } public CodeTreeBuilder getBuilder() { CodeTree tree = this.bodyTree; return createBuilder().tree(tree); } public CodeTreeBuilder createBuilder() { CodeTreeBuilder builder = new CodeTreeBuilder(null); builder.setEnclosingElement(this); this.bodyTree = builder.getTree(); this.body = null; return builder; } public void setBodyTree(CodeTree body) { this.bodyTree = body; } public CodeTree getBodyTree() { return bodyTree; } public TypeMirror getReturnType() { return returnType; } @Override public List getParameters() { return parameters; } public TypeMirror[] getParameterTypes() { TypeMirror[] types = new TypeMirror[getParameters().size()]; for (int i = 0; i < types.length; i++) { types[i] = parameters.get(i).asType(); } return types; } public void setReturnType(TypeMirror type) { returnType = type; } public void addParameter(VariableElement parameter) { parameters.add(parameter); } public void addThrownType(TypeMirror thrownType) { throwables.add(thrownType); } public void setSimpleName(Name name) { this.name = name; } public void setBody(String body) { this.body = body; } public String getBody() { return body; } @Override public R accept(ElementVisitor v, P p) { return v.visitExecutable(this, p); } public static CodeExecutableElement clone(@SuppressWarnings("unused") ProcessingEnvironment env, ExecutableElement method) { CodeExecutableElement copy = new CodeExecutableElement(method.getReturnType(), method.getSimpleName().toString()); for (TypeMirror thrownType : method.getThrownTypes()) { copy.addThrownType(thrownType); } copy.setDefaultValue(method.getDefaultValue()); for (AnnotationMirror mirror : method.getAnnotationMirrors()) { copy.addAnnotationMirror(mirror); } for (VariableElement var : method.getParameters()) { copy.addParameter(CodeVariableElement.clone(var)); } for (Element element : method.getEnclosedElements()) { copy.add(element); } copy.getModifiers().addAll(method.getModifiers()); copy.setVarArgs(method.isVarArgs()); return copy; } public TypeMirror getReceiverType() { throw new UnsupportedOperationException(); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/GeneratedElement.java0000644000000000000000000000254712445312576030060 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import javax.lang.model.element.*; public interface GeneratedElement { AnnotationMirror getGeneratorAnnotationMirror(); void setGeneratorAnnotationMirror(AnnotationMirror mirror); Element getGeneratorElement(); void setGeneratorElement(Element element); } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeCompilationUnit.java0000644000000000000000000000373012445312576030554 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; public class CodeCompilationUnit extends CodeElement { public CodeCompilationUnit() { super(Collections. emptySet()); } @Override public TypeMirror asType() { throw new UnsupportedOperationException(); } @Override public ElementKind getKind() { return ElementKind.OTHER; } @Override public Name getSimpleName() { throw new UnsupportedOperationException(); } @Override public R accept(ElementVisitor v, P p) { for (Element type : getEnclosedElements()) { if (type.getKind().isClass()) { type.accept(v, p); } else { throw new ClassCastException(type.getClass().getName()); } } return null; } } ././@LongLink0000644000000000000000000000015000000000000011577 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/GeneratedPackageElement.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/GeneratedPackageElement.j0000644000000000000000000000510512445312576030635 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; public final class GeneratedPackageElement extends CodeElement implements PackageElement { private final Name qualifiedName; private final Name simpleName; public GeneratedPackageElement(String qualifiedName) { super(Collections. emptySet()); this.qualifiedName = CodeNames.of(qualifiedName); int lastIndex = qualifiedName.lastIndexOf('.'); if (lastIndex == -1) { simpleName = CodeNames.of(""); } else { simpleName = CodeNames.of(qualifiedName.substring(lastIndex, qualifiedName.length())); } } public TypeMirror asType() { throw new UnsupportedOperationException(); } public ElementKind getKind() { return ElementKind.PACKAGE; } public R accept(ElementVisitor v, P p) { return v.visitPackage(this, p); } public Name getQualifiedName() { return qualifiedName; } public Name getSimpleName() { return simpleName; } public boolean isUnnamed() { return simpleName.toString().equals(""); } @Override public int hashCode() { return qualifiedName.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof PackageElement) { return qualifiedName.equals(((PackageElement) obj).getQualifiedName()); } return super.equals(obj); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeElement.java0000644000000000000000000002270312445312576027030 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.io.*; import java.lang.annotation.*; import java.util.*; import javax.lang.model.element.*; import com.oracle.truffle.dsl.processor.java.transform.*; public abstract class CodeElement implements Element, GeneratedElement { private final Set modifiers; private List annotations; private List enclosedElements; private Element enclosingElement; private Element generatorElement; private AnnotationMirror generatorAnnotationMirror; public CodeElement(Set modifiers) { this.modifiers = new LinkedHashSet<>(modifiers); } @Override public void setGeneratorAnnotationMirror(AnnotationMirror mirror) { this.generatorAnnotationMirror = mirror; } @Override public void setGeneratorElement(Element element) { this.generatorElement = element; } @Override public AnnotationMirror getGeneratorAnnotationMirror() { return generatorAnnotationMirror; } @Override public Element getGeneratorElement() { return generatorElement; } public E add(E element) { if (element == null) { throw new NullPointerException(); } getEnclosedElements().add(element); return element; } public E addOptional(E element) { if (element != null) { add(element); } return element; } public void remove(E element) { getEnclosedElements().remove(element); } @Override public Set getModifiers() { return modifiers; } @Override public List getEnclosedElements() { if (enclosedElements == null) { enclosedElements = parentableList(this, new ArrayList()); } return enclosedElements; } @Override public List getAnnotationMirrors() { if (annotations == null) { annotations = parentableList(this, new ArrayList()); } return annotations; } /** * Support JDK8 langtools. * * @param annotationType */ public A[] getAnnotationsByType(Class annotationType) { throw new UnsupportedOperationException(); } /** * Support for some JDK8 builds. (remove after jdk8 is released) * * @param annotationType */ public A[] getAnnotations(Class annotationType) { throw new UnsupportedOperationException(); } /** * Support for some JDK8 builds. (remove after jdk8 is released) * * @param annotationType */ public A getAnnotation(Class annotationType) { throw new UnsupportedOperationException(); } public void addAnnotationMirror(AnnotationMirror annotationMirror) { getAnnotationMirrors().add(annotationMirror); } public void setEnclosingElement(Element parent) { this.enclosingElement = parent; } public Element getEnclosingElement() { return enclosingElement; } public CodeTypeElement getEnclosingClass() { Element p = enclosingElement; while (p != null && p.getKind() != ElementKind.CLASS && p.getKind() != ElementKind.ENUM) { p = p.getEnclosingElement(); } return (CodeTypeElement) p; } List parentableList(Element parent, List list) { return new ParentableList<>(parent, list); } @Override public String toString() { StringBuilderCodeWriter codeWriter = new StringBuilderCodeWriter(); accept(codeWriter, null); return codeWriter.getString(); } private static class StringBuilderCodeWriter extends AbstractCodeWriter { public StringBuilderCodeWriter() { this.writer = new CharArrayWriter(); } @Override protected Writer createWriter(CodeTypeElement clazz) throws IOException { return writer; } public String getString() { return new String(((CharArrayWriter) writer).toCharArray()).trim(); } } private static class ParentableList implements List { private final Element parent; private final List delegate; public ParentableList(Element parent, List delegate) { this.parent = parent; this.delegate = delegate; } private void addImpl(T element) { if (element != null) { if (element instanceof CodeElement) { ((CodeElement) element).setEnclosingElement(parent); } } } private static void removeImpl(Object element) { if (element instanceof CodeElement) { ((CodeElement) element).setEnclosingElement(null); } } @Override public int size() { return delegate.size(); } @Override public boolean isEmpty() { return delegate.isEmpty(); } @Override public boolean contains(Object o) { return delegate.contains(o); } @Override public Iterator iterator() { return delegate.iterator(); } @Override public Object[] toArray() { return delegate.toArray(); } @Override public E[] toArray(E[] a) { return delegate.toArray(a); } @Override public boolean add(T e) { addImpl(e); return delegate.add(e); } @Override public boolean remove(Object o) { boolean removed = delegate.remove(o); if (removed) { removeImpl(o); } return removed; } @Override public boolean containsAll(Collection c) { return delegate.containsAll(c); } @Override public boolean addAll(Collection c) { if (c != null) { for (T t : c) { addImpl(t); } } return delegate.addAll(c); } @Override public boolean addAll(int index, Collection c) { if (c != null) { for (T t : c) { addImpl(t); } } return delegate.addAll(index, c); } @Override public boolean removeAll(Collection c) { if (c != null) { for (Object t : c) { removeImpl(t); } } return delegate.removeAll(c); } @Override public String toString() { return delegate.toString(); } @Override public boolean retainAll(Collection c) { throw new UnsupportedOperationException("Not supported by parentable list"); } @Override public void clear() { for (Object e : this) { removeImpl(e); } delegate.clear(); } @Override public T get(int index) { return delegate.get(index); } @Override public T set(int index, T element) { removeImpl(delegate.get(index)); addImpl(element); return delegate.set(index, element); } @Override public void add(int index, T element) { addImpl(element); delegate.add(index, element); } @Override public T remove(int index) { T element = delegate.remove(index); removeImpl(element); return element; } @Override public int indexOf(Object o) { return delegate.indexOf(o); } @Override public int lastIndexOf(Object o) { return delegate.lastIndexOf(o); } @Override public ListIterator listIterator() { return delegate.listIterator(); } @Override public ListIterator listIterator(int index) { return delegate.listIterator(index); } @Override public List subList(int fromIndex, int toIndex) { return new ParentableList<>(parent, delegate.subList(fromIndex, toIndex)); } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeImport.java0000644000000000000000000000536412445312576026715 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; public class CodeImport implements Comparable { private final String packageName; private final String symbolName; private final boolean staticImport; public CodeImport(String packageName, String symbolName, boolean staticImport) { this.packageName = packageName; this.symbolName = symbolName; this.staticImport = staticImport; } public String getPackageName() { return packageName; } public String getSymbolName() { return symbolName; } public boolean isStaticImport() { return staticImport; } @Override public int compareTo(CodeImport o) { if (staticImport && !o.staticImport) { return 1; } else if (!staticImport && o.staticImport) { return -1; } else { int result = getPackageName().compareTo(o.getPackageName()); if (result == 0) { return getSymbolName().compareTo(o.getSymbolName()); } return result; } } public

void accept(CodeElementScanner s, P p) { s.visitImport(this, p); } @Override public int hashCode() { return Objects.hash(packageName, symbolName, staticImport); } @Override public boolean equals(Object obj) { if (obj instanceof CodeImport) { CodeImport otherImport = (CodeImport) obj; return getPackageName().equals(otherImport.getPackageName()) && getSymbolName().equals(otherImport.getSymbolName()) // && staticImport == otherImport.staticImport; } return super.equals(obj); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeVariableElement.java0000644000000000000000000001001512445312576030467 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; public final class CodeVariableElement extends CodeElement implements VariableElement { private Name name; private TypeMirror type; private Object constantValue; private CodeTree init; public CodeVariableElement(TypeMirror type, String name) { super(ElementUtils.modifiers()); this.type = type; this.name = CodeNames.of(name); } public CodeVariableElement(Set modifiers, TypeMirror type, String name) { super(modifiers); this.type = type; this.name = CodeNames.of(name); } public CodeVariableElement(Set modifiers, TypeMirror type, String name, String init) { this(modifiers, type, name); if (init != null) { this.init = new CodeTree(null, CodeTreeKind.STRING, null, init); } } public CodeTreeBuilder createInitBuilder() { CodeTreeBuilder builder = new CodeTreeBuilder(null); builder.setEnclosingElement(this); init = builder.getTree(); return builder; } public void setInit(CodeTree init) { this.init = init; } public CodeTree getInit() { return init; } public Name getSimpleName() { return name; } public TypeMirror getType() { return type; } @Override public TypeMirror asType() { return type; } @Override public ElementKind getKind() { if (getEnclosingElement() instanceof ExecutableElement) { return ElementKind.PARAMETER; } else if (getEnclosingElement() instanceof TypeElement) { return ElementKind.FIELD; } else { return ElementKind.PARAMETER; } } public void setConstantValue(Object constantValue) { this.constantValue = constantValue; } @Override public Object getConstantValue() { return constantValue; } public String getName() { return getSimpleName().toString(); } public void setSimpleName(Name name) { this.name = name; } public void setName(String name) { this.name = CodeNames.of(name); } public void setType(TypeMirror type) { this.type = type; } @Override public R accept(ElementVisitor v, P p) { return v.visitVariable(this, p); } public static CodeVariableElement clone(VariableElement var) { CodeVariableElement copy = new CodeVariableElement(var.getModifiers(), var.asType(), var.getSimpleName().toString()); copy.setConstantValue(var.getConstantValue()); for (AnnotationMirror mirror : var.getAnnotationMirrors()) { copy.addAnnotationMirror(mirror); } for (Element element : var.getEnclosedElements()) { copy.add(element); } return copy; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeTree.java0000644000000000000000000000432412445312576026335 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.type.*; public class CodeTree { private final CodeTreeKind kind; private CodeTree parent; private TypeMirror type; private final String string; private List children; CodeTree(CodeTree parent, CodeTreeKind kind, TypeMirror type, String string) { this.parent = parent; this.kind = kind; this.type = type; this.string = string; } public void setParent(CodeTree parent) { this.parent = parent; } public CodeTree getParent() { return parent; } public TypeMirror getType() { return type; } public void add(CodeTree element) { if (children == null) { children = new ArrayList<>(); } element.setParent(this); children.add(element); } public final List getEnclosedElements() { return children; } public final CodeTreeKind getCodeKind() { return kind; } public String getString() { return string; } public void setType(TypeMirror type) { this.type = type; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/GeneratedTypeMirror.java0000644000000000000000000000300712445312576030573 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror; public final class GeneratedTypeMirror extends DeclaredCodeTypeMirror { public GeneratedTypeMirror(String packageName, String name) { super(new GeneratedTypeElement(Collections. emptySet(), ElementKind.CLASS, new GeneratedPackageElement(packageName), name)); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeTreeKind.java0000644000000000000000000000240412445312576027140 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; public enum CodeTreeKind { STATIC_FIELD_REFERENCE, STATIC_METHOD_REFERENCE, GROUP, COMMA_GROUP, REMOVE_LAST, INDENT, STRING, NEW_LINE, TYPE; } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java0000644000000000000000000006307412445312576027653 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import static com.oracle.truffle.dsl.processor.java.model.CodeTreeKind.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; public class CodeTreeBuilder { private BuilderCodeTree currentElement; private final BuilderCodeTree root; private int treeCount; private Element enclosingElement; public CodeTreeBuilder(CodeTreeBuilder parent) { this.root = new BuilderCodeTree(null, GROUP, null, null); this.currentElement = root; if (parent != null) { this.enclosingElement = parent.enclosingElement; } } public void setEnclosingElement(Element enclosingElement) { this.enclosingElement = enclosingElement; } @Override public String toString() { return root.toString(); } public int getTreeCount() { return treeCount; } public boolean isEmpty() { return treeCount == 0; } public CodeTreeBuilder statement(String statement) { return startStatement().string(statement).end(); } public CodeTreeBuilder statement(CodeTree statement) { return startStatement().tree(statement).end(); } public static CodeTreeBuilder createBuilder() { return new CodeTreeBuilder(null); } public static CodeTree singleString(String s) { return new CodeTreeBuilder(null).string(s).getTree(); } public static CodeTree singleType(TypeMirror s) { return new CodeTreeBuilder(null).type(s).getTree(); } private CodeTreeBuilder push(CodeTreeKind kind) { return push(new BuilderCodeTree(currentElement, kind, null, null), kind == NEW_LINE); } private CodeTreeBuilder push(String string) { return push(new BuilderCodeTree(currentElement, CodeTreeKind.STRING, null, string), false); } private CodeTreeBuilder push(TypeMirror type) { return push(new BuilderCodeTree(currentElement, CodeTreeKind.TYPE, type, null), false); } private CodeTreeBuilder push(CodeTreeKind kind, TypeMirror type, String string) { return push(new BuilderCodeTree(currentElement, kind, type, string), kind == NEW_LINE); } private CodeTreeBuilder push(BuilderCodeTree tree, boolean removeLast) { if (currentElement != null) { if (removeLast && !removeLastIfEnqueued(tree)) { return this; } currentElement.add(tree); } switch (tree.getCodeKind()) { case COMMA_GROUP: case GROUP: case INDENT: currentElement = tree; break; } treeCount++; return this; } private boolean removeLastIfEnqueued(BuilderCodeTree tree) { if (tree.getCodeKind() == REMOVE_LAST) { return !clearLastRec(tree.removeLast, currentElement.getEnclosedElements()); } List childTree = tree.getEnclosedElements(); if (childTree != null && !childTree.isEmpty()) { CodeTree last = childTree.get(0); if (last instanceof BuilderCodeTree) { if (!removeLastIfEnqueued((BuilderCodeTree) last)) { childTree.remove(0); } } } return true; } private void clearLast(CodeTreeKind kind) { if (clearLastRec(kind, currentElement.getEnclosedElements())) { treeCount--; } else { // delay clearing the last BuilderCodeTree tree = new BuilderCodeTree(currentElement, REMOVE_LAST, null, null); tree.removeLast = kind; push(tree, false); } } public CodeTreeBuilder startStatement() { startGroup(); registerCallBack(new EndCallback() { @Override public void beforeEnd() { string(";").newLine(); } @Override public void afterEnd() { } }); return this; } public CodeTreeBuilder startGroup() { return push(CodeTreeKind.GROUP); } public CodeTreeBuilder startCommaGroup() { return push(CodeTreeKind.COMMA_GROUP); } public CodeTreeBuilder startCall(String callSite) { return startCall((CodeTree) null, callSite); } public CodeTreeBuilder startCall(String receiver, String callSite) { return startCall(singleString(receiver), callSite); } public CodeTreeBuilder startCall(CodeTree receiver, String callSite) { if (receiver == null) { return startGroup().string(callSite).startParanthesesCommaGroup().endAfter(); } else { return startGroup().tree(receiver).string(".").string(callSite).startParanthesesCommaGroup().endAfter(); } } public CodeTreeBuilder startStaticCall(TypeMirror type, String methodName) { return startGroup().push(CodeTreeKind.STATIC_METHOD_REFERENCE, type, methodName).startParanthesesCommaGroup().endAfter(); } public CodeTreeBuilder startStaticCall(ExecutableElement method) { return startStaticCall(ElementUtils.findNearestEnclosingType(method).asType(), method.getSimpleName().toString()); } public CodeTreeBuilder staticReference(TypeMirror type, String fieldName) { return push(CodeTreeKind.STATIC_FIELD_REFERENCE, type, fieldName); } private CodeTreeBuilder endAndWhitespaceAfter() { registerCallBack(new EndCallback() { @Override public void beforeEnd() { } @Override public void afterEnd() { string(" "); end(); } }); return this; } private CodeTreeBuilder endAfter() { registerCallBack(new EndCallback() { @Override public void beforeEnd() { } @Override public void afterEnd() { end(); } }); return this; } private CodeTreeBuilder startParanthesesCommaGroup() { startGroup(); string("(").startCommaGroup(); registerCallBack(new EndCallback() { @Override public void beforeEnd() { } @Override public void afterEnd() { string(")"); } }); endAfter(); return this; } private CodeTreeBuilder startCurlyBracesCommaGroup() { startGroup(); string("{").startCommaGroup(); registerCallBack(new EndCallback() { @Override public void beforeEnd() { } @Override public void afterEnd() { string("}"); } }); endAfter(); return this; } public CodeTreeBuilder startParantheses() { startGroup(); string("(").startGroup(); registerCallBack(new EndCallback() { @Override public void beforeEnd() { } @Override public void afterEnd() { string(")"); } }); endAfter(); return this; } public CodeTreeBuilder doubleQuote(String s) { return startGroup().string("\"" + s + "\"").end(); } public CodeTreeBuilder string(String chunk1) { return push(chunk1); } public CodeTreeBuilder string(String chunk1, String chunk2) { return push(GROUP).string(chunk1).string(chunk2).end(); } public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3) { return push(GROUP).string(chunk1).string(chunk2).string(chunk3).end(); } public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4) { return push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4).end(); } public CodeTreeBuilder tree(CodeTree treeToAdd) { if (treeToAdd instanceof BuilderCodeTree) { return push((BuilderCodeTree) treeToAdd, true).end(); } else { BuilderCodeTree tree = new BuilderCodeTree(currentElement, GROUP, null, null); currentElement.add(treeToAdd); return push(tree, true).end(); } } public CodeTreeBuilder string(String chunk1, String chunk2, String chunk3, String chunk4, String... chunks) { push(GROUP).string(chunk1).string(chunk2).string(chunk3).string(chunk4); for (int i = 0; i < chunks.length; i++) { string(chunks[i]); } return end(); } public CodeTreeBuilder dot() { return string("."); } public CodeTreeBuilder newLine() { return push(NEW_LINE); } public CodeTreeBuilder startWhile() { return startGroup().string("while ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter(); } public CodeTreeBuilder startDoBlock() { return startGroup().string("do ").startBlock(); } public CodeTreeBuilder startDoWhile() { clearLast(CodeTreeKind.NEW_LINE); return startStatement().string(" while ").startParanthesesCommaGroup().endAfter().startGroup().endAfter(); } public CodeTreeBuilder startIf() { return startGroup().string("if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter(); } public CodeTreeBuilder startFor() { return startGroup().string("for ").startParantheses().endAndWhitespaceAfter().startGroup().endAfter(); } public boolean startIf(boolean elseIf) { if (elseIf) { startElseIf(); } else { startIf(); } return true; } public CodeTreeBuilder startElseIf() { clearLast(CodeTreeKind.NEW_LINE); return startGroup().string(" else if ").startParanthesesCommaGroup().endAndWhitespaceAfter().startGroup().endAfter(); } public CodeTreeBuilder startElseBlock() { clearLast(CodeTreeKind.NEW_LINE); return startGroup().string(" else ").startBlock().endAfter(); } private boolean clearLastRec(CodeTreeKind kind, List children) { if (children == null) { return false; } for (int i = children.size() - 1; i >= 0; i--) { CodeTree child = children.get(i); if (child.getCodeKind() == kind) { children.remove(children.get(i)); return true; } else { if (clearLastRec(kind, child.getEnclosedElements())) { return true; } } } return false; } public CodeTreeBuilder startCase() { startGroup().string("case "); registerCallBack(new EndCallback() { @Override public void beforeEnd() { string(" :").newLine(); } @Override public void afterEnd() { } }); return this; } public CodeTreeBuilder caseDefault() { return startGroup().string("default :").newLine().end(); } public CodeTreeBuilder startSwitch() { return startGroup().string("switch ").startParanthesesCommaGroup().endAndWhitespaceAfter(); } public CodeTreeBuilder startReturn() { ExecutableElement method = findMethod(); if (method != null && ElementUtils.isVoid(method.getReturnType())) { startGroup(); registerCallBack(new EndCallback() { @Override public void beforeEnd() { string(";").newLine(); // complete statement to execute } @Override public void afterEnd() { string("return").string(";").newLine(); // emit a return; } }); return this; } else { return startStatement().string("return "); } } public CodeTreeBuilder startAssert() { return startStatement().string("assert "); } public CodeTreeBuilder startNewArray(ArrayType arrayType, CodeTree size) { startGroup().string("new ").type(arrayType.getComponentType()).string("["); if (size != null) { tree(size); } string("]"); if (size == null) { string(" "); startCurlyBracesCommaGroup().endAfter(); } return this; } public CodeTreeBuilder startNew(TypeMirror uninializedNodeClass) { return startGroup().string("new ").type(uninializedNodeClass).startParanthesesCommaGroup().endAfter(); } public CodeTreeBuilder startNew(String typeName) { return startGroup().string("new ").string(typeName).startParanthesesCommaGroup().endAfter(); } public CodeTreeBuilder startIndention() { return push(CodeTreeKind.INDENT); } public CodeTreeBuilder end(int times) { for (int i = 0; i < times; i++) { end(); } return this; } public CodeTreeBuilder end() { BuilderCodeTree tree = currentElement; EndCallback callback = tree.getAtEndListener(); if (callback != null) { callback.beforeEnd(); toParent(); callback.afterEnd(); } else { toParent(); } return this; } private void toParent() { CodeTree parentElement = currentElement.getParent(); if (currentElement != root) { this.currentElement = (BuilderCodeTree) parentElement; } else { this.currentElement = root; } } public CodeTreeBuilder startBlock() { startGroup(); string("{").newLine().startIndention(); registerCallBack(new EndCallback() { @Override public void beforeEnd() { } @Override public void afterEnd() { string("}").newLine(); } }); endAfter(); return this; } private void registerCallBack(EndCallback callback) { currentElement.registerAtEnd(callback); } public CodeTreeBuilder defaultDeclaration(TypeMirror type, String name) { if (!ElementUtils.isVoid(type)) { startStatement(); type(type); string(" "); string(name); string(" = "); defaultValue(type); end(); // statement } return this; } public CodeTreeBuilder declaration(TypeMirror type, String name, String init) { return declaration(type, name, singleString(init)); } public CodeTreeBuilder declaration(String type, String name, CodeTree init) { startStatement(); string(type); string(" "); string(name); if (init != null) { string(" = "); tree(init); } end(); // statement return this; } public CodeTreeBuilder declaration(String type, String name, String init) { return declaration(type, name, singleString(init)); } public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTree init) { if (ElementUtils.isVoid(type)) { startStatement(); tree(init); end(); } else { startStatement(); type(type); string(" "); string(name); if (init != null) { string(" = "); tree(init); } end(); // statement } return this; } public CodeTreeBuilder declaration(TypeMirror type, String name, CodeTreeBuilder init) { if (init == this) { throw new IllegalArgumentException("Recursive builder usage."); } return declaration(type, name, init.getTree()); } public CodeTreeBuilder declaration(String type, String name, CodeTreeBuilder init) { if (init == this) { throw new IllegalArgumentException("Recursive builder usage."); } return declaration(type, name, init.getTree()); } public CodeTreeBuilder declaration(TypeMirror type, String name) { return declaration(type, name, (CodeTree) null); } public CodeTreeBuilder create() { return new CodeTreeBuilder(this); } public CodeTreeBuilder type(TypeMirror type) { return push(type); } public CodeTreeBuilder typeLiteral(TypeMirror type) { return startGroup().type(ElementUtils.eraseGenericTypes(type)).string(".class").end(); } private void assertRoot() { if (currentElement != root) { throw new IllegalStateException("CodeTreeBuilder was not ended properly."); } } public CodeTreeBuilder startCaseBlock() { return startIndention(); } public CodeTreeBuilder startThrow() { return startStatement().string("throw "); } public CodeTree getTree() { assertRoot(); return root; } public CodeTree getRoot() { return root; } public CodeTreeBuilder cast(String baseClassName) { string("(").string(baseClassName).string(") "); return this; } public CodeTreeBuilder cast(TypeMirror type, CodeTree content) { if (ElementUtils.isVoid(type)) { tree(content); return this; } else if (type.getKind() == TypeKind.DECLARED && ElementUtils.getQualifiedName(type).equals("java.lang.Object")) { tree(content); return this; } else { return startGroup().string("(").type(type).string(")").string(" ").tree(content).end(); } } public CodeTreeBuilder startSuperCall() { return string("super").startParanthesesCommaGroup(); } public CodeTreeBuilder returnFalse() { return startReturn().string("false").end(); } public CodeTreeBuilder returnStatement() { return statement("return"); } public ExecutableElement findMethod() { if (enclosingElement != null && (enclosingElement.getKind() == ElementKind.METHOD || enclosingElement.getKind() == ElementKind.CONSTRUCTOR)) { return (ExecutableElement) enclosingElement; } return null; } public CodeTreeBuilder returnNull() { return startReturn().string("null").end(); } public CodeTreeBuilder returnTrue() { return startReturn().string("true").end(); } public CodeTreeBuilder instanceOf(CodeTree var, CodeTree type) { tree(var).string(" instanceof ").tree(type); return this; } public CodeTreeBuilder instanceOf(String var, String type) { return instanceOf(singleString(var), singleString(type)); } public CodeTreeBuilder instanceOf(String var, TypeMirror type) { return instanceOf(singleString(var), singleType(type)); } public CodeTreeBuilder defaultValue(TypeMirror mirror) { switch (mirror.getKind()) { case VOID: return string(""); case ARRAY: case DECLARED: case PACKAGE: case NULL: return string("null"); case BOOLEAN: return string("false"); case BYTE: return string("(byte) 0"); case CHAR: return string("(char) 0"); case DOUBLE: return string("0.0D"); case LONG: return string("0L"); case INT: return string("0"); case FLOAT: return string("0.0F"); case SHORT: return string("(short) 0"); default: throw new AssertionError(); } } public CodeTreeBuilder assertFalse() { return startAssert().string("false").end(); } public CodeTreeBuilder breakStatement() { return statement("break"); } public CodeTreeBuilder isNull() { return string(" == null"); } public CodeTreeBuilder isNotNull() { return string(" != null"); } public CodeTreeBuilder is(CodeTree tree) { return string(" == ").tree(tree); } public CodeTreeBuilder startTryBlock() { return string("try ").startBlock(); } public CodeTreeBuilder startCatchBlock(TypeMirror exceptionType, String localVarName) { clearLast(CodeTreeKind.NEW_LINE); string(" catch (").type(exceptionType).string(" ").string(localVarName).string(") "); return startBlock(); } public CodeTreeBuilder startFinallyBlock() { clearLast(CodeTreeKind.NEW_LINE); string(" finally "); return startBlock(); } public CodeTreeBuilder nullLiteral() { return string("null"); } private static class BuilderCodeTree extends CodeTree { private EndCallback atEndListener; private CodeTreeKind removeLast; public BuilderCodeTree(CodeTree parent, CodeTreeKind kind, TypeMirror type, String string) { super(parent, kind, type, string); } public void registerAtEnd(EndCallback atEnd) { if (this.atEndListener != null) { this.atEndListener = new CompoundCallback(this.atEndListener, atEnd); } else { this.atEndListener = atEnd; } } public EndCallback getAtEndListener() { return atEndListener; } @Override public String toString() { final StringBuilder b = new StringBuilder(); new Printer(b).visitTree(this, null, null); return b.toString(); } private static class CompoundCallback implements EndCallback { private final EndCallback callback1; private final EndCallback callback2; public CompoundCallback(EndCallback callback1, EndCallback callback2) { this.callback1 = callback1; this.callback2 = callback2; } @Override public void afterEnd() { callback1.afterEnd(); callback2.afterEnd(); } @Override public void beforeEnd() { callback1.beforeEnd(); callback1.beforeEnd(); } } } private interface EndCallback { void beforeEnd(); void afterEnd(); } private static class Printer extends CodeElementScanner { private int indent; private boolean newLine; private final String ln = "\n"; private final StringBuilder b; Printer(StringBuilder b) { this.b = b; } @Override public void visitTree(CodeTree e, Void p, Element enclosingElement) { switch (e.getCodeKind()) { case COMMA_GROUP: List children = e.getEnclosedElements(); if (children != null) { for (int i = 0; i < children.size(); i++) { visitTree(children.get(i), p, enclosingElement); if (i < e.getEnclosedElements().size() - 1) { b.append(", "); } } } break; case GROUP: super.visitTree(e, p, enclosingElement); break; case INDENT: indent(); super.visitTree(e, p, enclosingElement); dedent(); break; case NEW_LINE: writeLn(); break; case STRING: if (e.getString() != null) { write(e.getString()); } else { write("null"); } break; case TYPE: write(ElementUtils.getSimpleName(e.getType())); break; default: assert false; return; } } private void indent() { indent++; } private void dedent() { indent--; } private void writeLn() { write(ln); newLine = true; } private void write(String m) { if (newLine && m != ln) { writeIndent(); newLine = false; } b.append(m); } private void writeIndent() { for (int i = 0; i < indent; i++) { b.append(" "); } } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeAnnotationValue.java0000644000000000000000000000704412445312576030547 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; public class CodeAnnotationValue implements AnnotationValue { private final Object value; public CodeAnnotationValue(Object value) { Objects.requireNonNull(value); if ((value instanceof AnnotationMirror) || (value instanceof List) || (value instanceof Boolean) || (value instanceof Byte) || (value instanceof Character) || (value instanceof Double) || (value instanceof VariableElement) || (value instanceof Float) || (value instanceof Integer) || (value instanceof Long) || (value instanceof Short) || (value instanceof String) || (value instanceof TypeMirror)) { this.value = value; } else { throw new IllegalArgumentException("Invalid annotation value type " + value.getClass().getName()); } } @Override public Object getValue() { return value; } @SuppressWarnings("unchecked") @Override public R accept(AnnotationValueVisitor v, P p) { if (value instanceof AnnotationMirror) { return v.visitAnnotation((AnnotationMirror) value, p); } else if (value instanceof List) { return v.visitArray((List) value, p); } else if (value instanceof Boolean) { return v.visitBoolean((boolean) value, p); } else if (value instanceof Byte) { return v.visitByte((byte) value, p); } else if (value instanceof Character) { return v.visitChar((char) value, p); } else if (value instanceof Double) { return v.visitDouble((double) value, p); } else if (value instanceof VariableElement) { return v.visitEnumConstant((VariableElement) value, p); } else if (value instanceof Float) { return v.visitFloat((float) value, p); } else if (value instanceof Integer) { return v.visitInt((int) value, p); } else if (value instanceof Long) { return v.visitLong((long) value, p); } else if (value instanceof Short) { return v.visitShort((short) value, p); } else if (value instanceof String) { return v.visitString((String) value, p); } else if (value instanceof TypeMirror) { return v.visitType((TypeMirror) value, p); } else { return v.visitUnknown(this, p); } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/java/model/CodeElementScanner.java0000644000000000000000000000557312445312576030350 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.java.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.util.*; public abstract class CodeElementScanner extends ElementScanner7 { @Override public final R visitExecutable(ExecutableElement e, P p) { return visitExecutable(cast(e, CodeExecutableElement.class), p); } public R visitExecutable(CodeExecutableElement e, P p) { R ret = super.visitExecutable(e, p); if (e.getBodyTree() != null) { visitTree(e.getBodyTree(), p, e); } return ret; } @Override public R visitVariable(VariableElement e, P p) { if (e instanceof CodeVariableElement) { CodeTree init = ((CodeVariableElement) e).getInit(); if (init != null) { visitTree(init, p, e); } } return super.visitVariable(e, p); } @Override public R visitPackage(PackageElement e, P p) { return super.visitPackage(e, p); } @Override public final R visitType(TypeElement e, P p) { return visitType(cast(e, CodeTypeElement.class), p); } public R visitType(CodeTypeElement e, P p) { return super.visitType(e, p); } @Override public R visitTypeParameter(TypeParameterElement e, P p) { return super.visitTypeParameter(e, p); } private static E cast(Element element, Class clazz) { return clazz.cast(element); } public void visitTree(CodeTree e, P p, Element parent) { List elements = e.getEnclosedElements(); if (elements != null) { for (CodeTree tree : e.getEnclosedElements()) { visitTree(tree, p, parent); } } } @SuppressWarnings("unused") public void visitImport(CodeImport e, P p) { } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/Log.java0000644000000000000000000000441212445312576023341 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor; import javax.annotation.processing.*; import javax.lang.model.element.*; import javax.tools.Diagnostic.Kind; import com.oracle.truffle.dsl.processor.java.model.*; /** * THIS IS NOT PUBLIC API. */ public class Log { public static final boolean DEBUG = false; private final ProcessingEnvironment processingEnv; public Log(ProcessingEnvironment env) { this.processingEnv = env; } public void message(Kind kind, Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) { AnnotationMirror usedMirror = mirror; Element usedElement = element; AnnotationValue usedValue = value; String message = String.format(format, args); if (element instanceof GeneratedElement) { usedMirror = ((GeneratedElement) element).getGeneratorAnnotationMirror(); usedElement = ((GeneratedElement) element).getGeneratorElement(); usedValue = null; if (usedElement != null) { message = String.format("Element %s: %s", element, message); } } processingEnv.getMessager().printMessage(kind, message, usedElement, usedMirror, usedValue); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/TruffleTypes.java0000644000000000000000000001604112445312576025255 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.tools.Diagnostic.Kind; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.dsl.internal.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; import com.oracle.truffle.api.source.*; /** * THIS IS NOT PUBLIC API. */ public final class TruffleTypes { public static final String OPTION_DETAILED_REWRITE_REASONS = "DetailedRewriteReasons"; private final DeclaredType node; private final ArrayType nodeArray; private final TypeMirror unexpectedValueException; private final TypeMirror frame; private final TypeMirror assumption; private final TypeMirror invalidAssumption; private final DeclaredType childAnnotation; private final DeclaredType childrenAnnotation; private final DeclaredType nodeInfoAnnotation; private final DeclaredType nodeCost; private final TypeMirror compilerDirectives; private final TypeMirror compilerAsserts; private final DeclaredType truffleBoundary; private final DeclaredType sourceSection; private final DeclaredType truffleOptions; private final DeclaredType compilationFinal; private final DeclaredType nodeUtil; private final DeclaredType dslNode; private final DeclaredType dslShare; private final DeclaredType nodeFactory; private final DeclaredType nodeFactoryBase; private final DeclaredType dslMetadata; private final DeclaredType implies; private final TypeElement expectError; private final List errors = new ArrayList<>(); TruffleTypes(ProcessorContext context) { node = getRequired(context, Node.class); nodeArray = context.getEnvironment().getTypeUtils().getArrayType(node); unexpectedValueException = getRequired(context, UnexpectedResultException.class); frame = getRequired(context, VirtualFrame.class); childAnnotation = getRequired(context, Child.class); childrenAnnotation = getRequired(context, Children.class); compilerDirectives = getRequired(context, CompilerDirectives.class); compilerAsserts = getRequired(context, CompilerAsserts.class); assumption = getRequired(context, Assumption.class); invalidAssumption = getRequired(context, InvalidAssumptionException.class); nodeInfoAnnotation = getRequired(context, NodeInfo.class); nodeCost = getRequired(context, NodeCost.class); truffleBoundary = getRequired(context, TruffleBoundary.class); sourceSection = getRequired(context, SourceSection.class); truffleOptions = getRequired(context, TruffleOptions.class); compilationFinal = getRequired(context, CompilationFinal.class); nodeUtil = getRequired(context, NodeUtil.class); dslNode = getRequired(context, DSLNode.class); dslShare = getRequired(context, DSLShare.class); nodeFactory = getRequired(context, NodeFactory.class); nodeFactoryBase = getRequired(context, NodeFactoryBase.class); dslMetadata = getRequired(context, DSLMetadata.class); implies = getRequired(context, Implies.class); expectError = (TypeElement) getRequired(context, ExpectError.class).asElement(); } public DeclaredType getImplies() { return implies; } public DeclaredType getDslMetadata() { return dslMetadata; } public DeclaredType getNodeFactory() { return nodeFactory; } public DeclaredType getNodeFactoryBase() { return nodeFactoryBase; } public DeclaredType getDslNode() { return dslNode; } public DeclaredType getDslShare() { return dslShare; } public DeclaredType getCompilationFinal() { return compilationFinal; } public TypeElement getExpectError() { return expectError; } public DeclaredType getNodeInfoAnnotation() { return nodeInfoAnnotation; } public boolean verify(ProcessorContext context, Element element, AnnotationMirror mirror) { if (errors.isEmpty()) { return true; } for (String error : errors) { context.getLog().message(Kind.ERROR, element, mirror, null, error); } return false; } public DeclaredType getNodeCost() { return nodeCost; } private DeclaredType getRequired(ProcessorContext context, Class clazz) { TypeMirror type = context.getType(clazz); if (type == null) { errors.add(String.format("Could not find required type: %s", clazz.getSimpleName())); } return (DeclaredType) type; } public TypeMirror getInvalidAssumption() { return invalidAssumption; } public TypeMirror getAssumption() { return assumption; } public TypeMirror getCompilerDirectives() { return compilerDirectives; } public DeclaredType getNode() { return node; } public ArrayType getNodeArray() { return nodeArray; } public TypeMirror getFrame() { return frame; } public TypeMirror getUnexpectedValueException() { return unexpectedValueException; } public DeclaredType getChildAnnotation() { return childAnnotation; } public DeclaredType getChildrenAnnotation() { return childrenAnnotation; } public TypeMirror getCompilerAsserts() { return compilerAsserts; } public DeclaredType getTruffleOptions() { return truffleOptions; } public DeclaredType getTruffleBoundary() { return truffleBoundary; } public DeclaredType getSourceSection() { return sourceSection; } public DeclaredType getNodeUtil() { return nodeUtil; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/0000755000000000000000000000000012460760144023735 5ustar ././@LongLink0000644000000000000000000000015200000000000011601 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/AbstractCodeElementFactory.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/AbstractCodeElementFactory0000644000000000000000000000453712445312576031076 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.generator; import javax.lang.model.element.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.model.*; public abstract class AbstractCodeElementFactory { protected final ProcessorContext context; private M model; private CodeElement element; public AbstractCodeElementFactory() { this.context = ProcessorContext.getInstance(); } protected abstract CodeElement create(M m); @SuppressWarnings("unused") protected void createChildren(M m) { } @SuppressWarnings({"unchecked", "rawtypes"}) public CodeElement process(CodeElement parent, M m) { model = m; element = (CodeElement) create(model); if (parent != null) { parent.add(element); } if (element != null) { createChildren(model); } return element; } @SuppressWarnings("rawtypes") public CodeElement getElement() { return element; } protected void add(AbstractCodeElementFactory factory, MO m) { factory.process(this.element, m); } public ProcessorContext getContext() { return context; } public M getModel() { return model; } } ././@LongLink0000644000000000000000000000014700000000000011605 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.ja0000644000000000000000000003254712445312576031061 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.generator; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import static javax.lang.model.element.Modifier.*; import java.util.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.model.*; public class TypeSystemCodeGenerator extends AbstractCompilationUnitFactory { public static String isTypeMethodName(TypeData type) { return "is" + ElementUtils.getTypeId(type.getBoxedType()); } public static String isImplicitTypeMethodName(TypeData type) { return "isImplicit" + ElementUtils.getTypeId(type.getBoxedType()); } public static String asTypeMethodName(TypeData type) { return "as" + ElementUtils.getTypeId(type.getBoxedType()); } public static String asImplicitTypeMethodName(TypeData type) { return "asImplicit" + ElementUtils.getTypeId(type.getBoxedType()); } public static String getImplicitClass(TypeData type) { return "getImplicit" + ElementUtils.getTypeId(type.getBoxedType()) + "Class"; } public static String expectTypeMethodName(TypeData type) { return "expect" + ElementUtils.getTypeId(type.getBoxedType()); } public static String typeName(TypeSystemData typeSystem) { String name = getSimpleName(typeSystem.getTemplateType()); return name + "Gen"; } public static String singletonName(TypeSystemData type) { return createConstantName(getSimpleName(type.getTemplateType().asType())); } @Override protected void createChildren(TypeSystemData m) { add(new TypeClassFactory(), m); } private static class TypeClassFactory extends AbstractClassElementFactory { private static final String LOCAL_VALUE = "value"; @Override public CodeTypeElement create(TypeSystemData typeSystem) { String name = typeName(typeSystem); CodeTypeElement clazz = createClass(typeSystem, modifiers(PUBLIC, FINAL), name, typeSystem.getTemplateType().asType(), false); clazz.add(createConstructorUsingFields(modifiers(PROTECTED), clazz)); CodeVariableElement singleton = createSingleton(clazz); clazz.add(singleton); for (TypeData type : typeSystem.getTypes()) { if (type.isGeneric() || type.isVoid()) { continue; } clazz.addOptional(createIsTypeMethod(type)); clazz.addOptional(createAsTypeMethod(type)); for (TypeData sourceType : collectExpectSourceTypes(type)) { clazz.addOptional(createExpectTypeMethod(type, sourceType)); } clazz.addOptional(createAsImplicitTypeMethod(type, true)); clazz.addOptional(createAsImplicitTypeMethod(type, false)); clazz.addOptional(createIsImplicitTypeMethod(type, true)); clazz.addOptional(createIsImplicitTypeMethod(type, false)); clazz.addOptional(createGetTypeIndex(type)); } return clazz; } private static List collectExpectSourceTypes(TypeData type) { Set sourceTypes = new HashSet<>(); sourceTypes.add(type.getTypeSystem().getGenericTypeData()); for (TypeCastData cast : type.getTypeCasts()) { sourceTypes.add(cast.getSourceType()); } for (TypeCheckData cast : type.getTypeChecks()) { sourceTypes.add(cast.getCheckedType()); } return new ArrayList<>(sourceTypes); } private CodeVariableElement createSingleton(CodeTypeElement clazz) { CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(getModel())); field.createInitBuilder().startNew(clazz.asType()).end(); return field; } private CodeExecutableElement createIsImplicitTypeMethod(TypeData type, boolean typed) { TypeSystemData typeSystem = getModel(); List casts = typeSystem.lookupByTargetType(type); if (casts.isEmpty()) { return null; } CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type)); method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); if (typed) { method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "typeHint")); } CodeTreeBuilder builder = method.createBuilder(); List sourceTypes = typeSystem.lookupSourceTypes(type); builder.startReturn(); String sep = ""; for (TypeData sourceType : sourceTypes) { builder.string(sep); if (typed) { builder.string("(typeHint == ").typeLiteral(sourceType.getPrimitiveType()).string(" && "); } builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end(); if (typed) { builder.string(")"); } if (sourceTypes.lastIndexOf(sourceType) != sourceTypes.size() - 1) { builder.newLine(); } if (sep.equals("")) { builder.startIndention(); } sep = " || "; } builder.end(); builder.end(); return method; } private CodeExecutableElement createAsImplicitTypeMethod(TypeData type, boolean typed) { TypeSystemData typeSystem = getModel(); List casts = typeSystem.lookupByTargetType(type); if (casts.isEmpty()) { return null; } CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type)); method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); if (typed) { method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "typeHint")); } List sourceTypes = typeSystem.lookupSourceTypes(type); CodeTreeBuilder builder = method.createBuilder(); boolean elseIf = false; for (TypeData sourceType : sourceTypes) { elseIf = builder.startIf(elseIf); if (typed) { builder.string("typeHint == ").typeLiteral(sourceType.getPrimitiveType()); } else { builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end(); } builder.end().startBlock(); builder.startReturn(); ImplicitCastData cast = typeSystem.lookupCast(sourceType, type); if (cast != null) { builder.startCall(cast.getMethodName()); } builder.startCall(asTypeMethodName(sourceType)).string(LOCAL_VALUE).end(); if (cast != null) { builder.end(); } builder.end(); builder.end(); } builder.startElseBlock(); builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end(); builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); builder.end(); return method; } private CodeExecutableElement createGetTypeIndex(TypeData type) { TypeSystemData typeSystem = getModel(); List casts = typeSystem.lookupByTargetType(type); if (casts.isEmpty()) { return null; } CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type)); method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); List sourceTypes = typeSystem.lookupSourceTypes(type); CodeTreeBuilder builder = method.createBuilder(); boolean elseIf = false; for (TypeData sourceType : sourceTypes) { elseIf = builder.startIf(elseIf); builder.startCall(isTypeMethodName(sourceType)).string(LOCAL_VALUE).end(); builder.end().startBlock(); builder.startReturn().typeLiteral(sourceType.getPrimitiveType()).end(); builder.end(); } builder.startElseBlock(); builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end(); builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); builder.end(); return method; } private CodeExecutableElement createIsTypeMethod(TypeData type) { if (!type.getTypeChecks().isEmpty()) { return null; } CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type)); method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); DeclaredType suppressWarnings = (DeclaredType) getContext().getType(SuppressWarnings.class); CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror(suppressWarnings); annotationMirror.setElementValue(annotationMirror.findExecutableElement("value"), new CodeAnnotationValue("static-method")); method.getAnnotationMirrors().add(annotationMirror); CodeTreeBuilder body = method.createBuilder(); body.startReturn().instanceOf(LOCAL_VALUE, type.getBoxedType()).end(); return method; } private CodeExecutableElement createAsTypeMethod(TypeData type) { if (!type.getTypeCasts().isEmpty()) { return null; } CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type)); method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); CodeTreeBuilder body = method.createBuilder(); String assertMessage = typeName(getModel()) + "." + asTypeMethodName(type) + ": " + ElementUtils.getSimpleName(type.getBoxedType()) + " expected"; body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().string(" : ").doubleQuote(assertMessage).end(); body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end(); return method; } private CodeExecutableElement createExpectTypeMethod(TypeData expectedType, TypeData sourceType) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType)); method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE)); method.addThrownType(getContext().getTruffleTypes().getUnexpectedValueException()); CodeTreeBuilder body = method.createBuilder(); body.startIf().startCall(TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock(); body.startReturn().startCall(TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end(); body.end(); // if-block body.startThrow().startNew(getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end(); return method; } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java0000644000000000000000000042402312445312576030141 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.generator; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import static javax.lang.model.element.Modifier.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror; import com.oracle.truffle.dsl.processor.model.*; import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; import com.oracle.truffle.dsl.processor.parser.*; import com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard; public class NodeCodeGenerator extends AbstractCompilationUnitFactory { private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode"; private static final String EXECUTE_CHAINED = "executeChained0"; private static final String SPECIALIZE = "specialize0"; private static final String DSLSHARE_REWRITE = "rewrite"; private static final String DSLSHARE_FIND_ROOT = "findRoot"; private static final String DSLSHARE_REWRITE_TO_POLYMORHPIC = "rewriteToPolymorphic"; private static final String EXECUTE_UNINITIALIZED = "executeUninitialized0"; private static final String REWRITE = "rewrite0"; private static final String CREATE_INFO = "createInfo0"; private static final String CONTAINS_FALLBACK = "containsFallback"; private static final String FACTORY_METHOD_NAME = "create0"; private static final String EMPTY_CLASS_ARRAY = "EMPTY_CLASS_ARRAY"; private static final String METADATA_FIELD_NAME = "METADATA"; private TypeMirror getUnexpectedValueException() { return getContext().getTruffleTypes().getUnexpectedValueException(); } private static String factoryClassName(NodeData node) { return node.getNodeId() + "Factory"; } private static String nodeSpecializationClassName(SpecializationData specialization) { String nodeid = resolveNodeId(specialization.getNode()); String name = ElementUtils.firstLetterUpperCase(nodeid); name += ElementUtils.firstLetterUpperCase(specialization.getId()); name += "Node"; return name; } private static String nodePolymorphicClassName(NodeData node) { return ElementUtils.firstLetterUpperCase(resolveNodeId(node)) + "PolymorphicNode"; } private static String resolveNodeId(NodeData node) { String nodeid = node.getNodeId(); if (nodeid.endsWith("Node") && !nodeid.equals("Node")) { nodeid = nodeid.substring(0, nodeid.length() - 4); } return nodeid; } private static String valueNameEvaluated(Parameter targetParameter) { return valueName(targetParameter) + "Evaluated"; } private static String implicitTypeName(Parameter param) { return param.getLocalName() + "ImplicitType"; } private static String polymorphicTypeName(NodeExecutionData param) { return param.getName() + "PolymorphicType"; } private static String valueName(Parameter param) { return param.getLocalName(); } private static CodeTree createAccessChild(NodeExecutionData targetExecution, String thisReference) { String reference = thisReference; if (reference == null) { reference = "this"; } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); Element accessElement = targetExecution.getChild().getAccessElement(); if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) { builder.string(reference).string(".").string(targetExecution.getChild().getName()); } else if (accessElement.getKind() == ElementKind.FIELD) { builder.string(reference).string(".").string(accessElement.getSimpleName().toString()); } else { throw new AssertionError(); } if (targetExecution.isIndexed()) { builder.string("[" + targetExecution.getIndex() + "]"); } return builder.getRoot(); } private static String castValueName(Parameter parameter) { return valueName(parameter) + "Cast"; } private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean disableFrame, boolean evaluated) { if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) { method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); } for (Parameter parameter : specialization.getParameters()) { ParameterSpec spec = parameter.getSpecification(); if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { continue; } if (spec.isLocal()) { continue; } String name = valueName(parameter); if (evaluated && spec.isSignature()) { name = valueNameEvaluated(parameter); } method.addParameter(new CodeVariableElement(parameter.getType(), name)); } } private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean disableFrame, Map customNames) { if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) { builder.string("frameValue"); } for (Parameter parameter : specialization.getParameters()) { ParameterSpec spec = parameter.getSpecification(); if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { continue; } if (parameter.getSpecification().isLocal()) { continue; } Parameter sourceParameter = source.findParameter(parameter.getLocalName()); if (customNames != null && customNames.containsKey(parameter.getLocalName())) { builder.string(customNames.get(parameter.getLocalName())); } else if (unexpectedValueName != null && parameter.getLocalName().equals(unexpectedValueName)) { builder.cast(parameter.getType(), CodeTreeBuilder.singleString("ex.getResult()")); } else if (sourceParameter != null) { builder.string(valueName(sourceParameter, parameter)); } else { builder.string(valueName(parameter)); } } } private static String valueName(Parameter sourceParameter, Parameter targetParameter) { if (!sourceParameter.getSpecification().isSignature()) { return valueName(targetParameter); } else if (sourceParameter.getTypeSystemType() != null && targetParameter.getTypeSystemType() != null) { if (sourceParameter.getTypeSystemType().needsCastTo(targetParameter.getTypeSystemType())) { return castValueName(targetParameter); } } return valueName(targetParameter); } private static CodeTree createTemplateMethodCall(CodeTreeBuilder parent, CodeTree target, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName, String... customSignatureValueNames) { CodeTreeBuilder builder = parent.create(); boolean castedValues = sourceMethod != targetMethod; builder.startGroup(); ExecutableElement method = targetMethod.getMethod(); if (method == null) { throw new UnsupportedOperationException(); } TypeElement targetClass = ElementUtils.findNearestEnclosingType(method.getEnclosingElement()); NodeData node = (NodeData) targetMethod.getTemplate(); if (target == null) { boolean accessible = targetMethod.canBeAccessedByInstanceOf(node.getNodeType()); if (accessible) { if (builder.findMethod().getModifiers().contains(STATIC)) { if (method.getModifiers().contains(STATIC)) { builder.type(targetClass.asType()); } else { builder.string(THIS_NODE_LOCAL_VAR_NAME); } } else { if (targetMethod instanceof ExecutableTypeData) { builder.string("this"); } else { builder.string("super"); } } } else { if (method.getModifiers().contains(STATIC)) { builder.type(targetClass.asType()); } else { Parameter firstParameter = null; for (Parameter searchParameter : targetMethod.getParameters()) { if (searchParameter.getSpecification().isSignature()) { firstParameter = searchParameter; break; } } if (firstParameter == null) { throw new AssertionError(); } Parameter sourceParameter = sourceMethod.findParameter(firstParameter.getLocalName()); if (castedValues && sourceParameter != null) { builder.string(valueName(sourceParameter, firstParameter)); } else { builder.string(valueName(firstParameter)); } } } builder.string("."); } else { builder.tree(target); } builder.startCall(method.getSimpleName().toString()); int signatureIndex = 0; for (Parameter targetParameter : targetMethod.getParameters()) { Parameter valueParameter = null; if (sourceMethod != null) { valueParameter = sourceMethod.findParameter(targetParameter.getLocalName()); } if (valueParameter == null) { valueParameter = targetParameter; } TypeMirror targetType = targetParameter.getType(); TypeMirror valueType = null; if (valueParameter != null) { valueType = valueParameter.getType(); } if (signatureIndex < customSignatureValueNames.length && targetParameter.getSpecification().isSignature()) { builder.string(customSignatureValueNames[signatureIndex]); signatureIndex++; } else if (targetParameter.getSpecification().isLocal()) { builder.startGroup(); if (builder.findMethod().getModifiers().contains(Modifier.STATIC)) { builder.string(THIS_NODE_LOCAL_VAR_NAME).string("."); } else { builder.string("this."); } builder.string(targetParameter.getSpecification().getName()); builder.end(); } else if (unexpectedValueName != null && targetParameter.getLocalName().equals(unexpectedValueName)) { builder.cast(targetParameter.getType(), CodeTreeBuilder.singleString("ex.getResult()")); } else if (!ElementUtils.needsCastTo(valueType, targetType)) { builder.startGroup(); builder.string(valueName(targetParameter)); builder.end(); } else { builder.string(castValueName(targetParameter)); } } builder.end().end(); return builder.getRoot(); } private static String baseClassName(NodeData node) { String nodeid = resolveNodeId(node); String name = ElementUtils.firstLetterUpperCase(nodeid); name += "BaseNode"; return name; } private static CodeTree createCallTypeSystemMethod(CodeTreeBuilder parent, NodeData node, String methodName, CodeTree... args) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); startCallTypeSystemMethod(builder, node.getTypeSystem(), methodName); for (CodeTree arg : args) { builder.tree(arg); } builder.end().end(); return builder.getRoot(); } private static void startCallTypeSystemMethod(CodeTreeBuilder body, TypeSystemData typeSystem, String methodName) { GeneratedTypeMirror typeMirror = new GeneratedTypeMirror(ElementUtils.getPackageName(typeSystem.getTemplateType()), TypeSystemCodeGenerator.typeName(typeSystem)); body.startGroup(); body.staticReference(typeMirror, TypeSystemCodeGenerator.singletonName(typeSystem)); body.string(".").startCall(methodName); } /** *

     * variant1 $condition != null
     *
     * $type $name = defaultValue($type);
     * if ($condition) {
     *     $name = $value;
     * }
     *
     * variant2 $condition != null
     * $type $name = $value;
     * 
* * . */ private static CodeTree createLazyAssignment(CodeTreeBuilder parent, String name, TypeMirror type, CodeTree condition, CodeTree value) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (condition == null) { builder.declaration(type, name, value); } else { builder.declaration(type, name, new CodeTreeBuilder(parent).defaultValue(type).getRoot()); builder.startIf().tree(condition).end(); builder.startBlock(); builder.startStatement(); builder.string(name); builder.string(" = "); builder.tree(value); builder.end(); // statement builder.end(); // block } return builder.getRoot(); } private void emitEncounteredSynthetic(CodeTreeBuilder builder, TemplateMethod current) { CodeTreeBuilder nodes = builder.create(); CodeTreeBuilder arguments = builder.create(); nodes.startCommaGroup(); arguments.startCommaGroup(); boolean empty = true; for (Parameter parameter : current.getParameters()) { NodeExecutionData executionData = parameter.getSpecification().getExecution(); if (executionData != null) { if (executionData.isShortCircuit()) { nodes.nullLiteral(); arguments.string(valueName(parameter.getPreviousParameter())); } nodes.tree(createAccessChild(executionData, "rootNode")); arguments.string(valueName(parameter)); empty = false; } } nodes.end(); arguments.end(); builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerDirectives(), "transferToInterpreter").end().end(); builder.declaration(baseClassName(getModel()), "rootNode", builder.create().startStaticCall(context.getTruffleTypes().getDslShare(), DSLSHARE_FIND_ROOT).string("this").end()); builder.startThrow().startNew(getContext().getType(UnsupportedSpecializationException.class)); builder.string("rootNode"); builder.startNewArray(getContext().getTruffleTypes().getNodeArray(), null); builder.tree(nodes.getRoot()); builder.end(); if (!empty) { builder.tree(arguments.getRoot()); } builder.end().end(); } private static List findUserConstructors(TypeMirror nodeType) { List constructors = new ArrayList<>(); for (ExecutableElement constructor : ElementFilter.constructorsIn(ElementUtils.fromTypeMirror(nodeType).getEnclosedElements())) { if (constructor.getModifiers().contains(PRIVATE)) { continue; } if (isCopyConstructor(constructor)) { continue; } constructors.add(constructor); } if (constructors.isEmpty()) { constructors.add(new CodeExecutableElement(null, ElementUtils.getSimpleName(nodeType))); } return constructors; } private static ExecutableElement findCopyConstructor(TypeMirror type) { for (ExecutableElement constructor : ElementFilter.constructorsIn(ElementUtils.fromTypeMirror(type).getEnclosedElements())) { if (constructor.getModifiers().contains(PRIVATE)) { continue; } if (isCopyConstructor(constructor)) { return constructor; } } return null; } private static boolean isCopyConstructor(ExecutableElement element) { if (element.getParameters().size() != 1) { return false; } VariableElement var = element.getParameters().get(0); TypeElement enclosingType = ElementUtils.findNearestEnclosingType(var); if (ElementUtils.typeEquals(var.asType(), enclosingType.asType())) { return true; } List types = ElementUtils.getDirectSuperTypes(enclosingType); for (TypeElement type : types) { if (!(type instanceof CodeTypeElement)) { // no copy constructors which are not generated types return false; } if (ElementUtils.typeEquals(var.asType(), type.asType())) { return true; } } return false; } @Override @SuppressWarnings("unchecked") protected void createChildren(NodeData node) { List casts = new ArrayList<>(getElement().getEnclosedElements()); getElement().getEnclosedElements().clear(); Map> childTypes = new LinkedHashMap<>(); for (NodeData nodeChild : node.getEnclosingNodes()) { NodeCodeGenerator generator = new NodeCodeGenerator(); childTypes.put(nodeChild, generator.process(null, nodeChild).getEnclosedElements()); } if (node.needsFactory() || node.getNodeDeclaringChildren().size() > 0) { NodeFactoryFactory factory = new NodeFactoryFactory(childTypes); add(factory, node); factory.getElement().getEnclosedElements().addAll(casts); } } private static CodeTree createCastType(TypeSystemData typeSystem, TypeData sourceType, TypeData targetType, boolean expect, CodeTree value) { if (targetType == null) { return value; } else if (sourceType != null && !sourceType.needsCastTo(targetType)) { return value; } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); String targetMethodName; if (expect) { targetMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetType); } else { targetMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType); } startCallTypeSystemMethod(builder, typeSystem, targetMethodName); builder.tree(value); builder.end().end(); return builder.getRoot(); } private static CodeTree createExpectType(TypeSystemData typeSystem, TypeData sourceType, TypeData targetType, CodeTree expression) { return createCastType(typeSystem, sourceType, targetType, true, expression); } private CodeTree createDeoptimize(CodeTreeBuilder parent) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); builder.startStatement(); builder.startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end(); builder.end(); return builder.getRoot(); } private class NodeFactoryFactory extends AbstractClassElementFactory { private final Map> childTypes; private CodeTypeElement generatedNode; public NodeFactoryFactory(Map> childElements) { this.childTypes = childElements; } @Override protected CodeTypeElement create(NodeData node) { Modifier visibility = ElementUtils.getVisibility(node.getTemplateType().getModifiers()); CodeTypeElement clazz = createClass(node, modifiers(), factoryClassName(node), null, false); if (visibility != null) { clazz.getModifiers().add(visibility); } clazz.getModifiers().add(Modifier.FINAL); return clazz; } @Override protected void createChildren(NodeData node) { CodeTypeElement clazz = getElement(); Modifier createVisibility = ElementUtils.getVisibility(clazz.getModifiers()); if (node.needsFactory()) { NodeBaseFactory factory = new NodeBaseFactory(); add(factory, node.getGenericSpecialization() == null ? node.getSpecializations().get(0) : node.getGenericSpecialization()); generatedNode = factory.getElement(); createFactoryMethods(node, clazz, createVisibility); for (SpecializationData specialization : node.getSpecializations()) { if (!specialization.isReachable() || specialization.isGeneric()) { continue; } if (specialization.isPolymorphic() && node.isPolymorphic(context)) { PolymorphicNodeFactory polymorphicFactory = new PolymorphicNodeFactory(generatedNode); add(polymorphicFactory, specialization); continue; } add(new SpecializedNodeFactory(generatedNode), specialization); } TypeMirror nodeFactory = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(getContext().getTruffleTypes().getNodeFactoryBase()), node.getNodeType()); clazz.setSuperClass(nodeFactory); clazz.add(createNodeFactoryConstructor(node)); clazz.add(createCreateNodeMethod(node)); clazz.add(createGetInstanceMethod(node, createVisibility)); clazz.add(createInstanceConstant(node, clazz.asType())); } for (NodeData childNode : childTypes.keySet()) { if (childNode.getTemplateType().getModifiers().contains(Modifier.PRIVATE)) { continue; } for (TypeElement type : childTypes.get(childNode)) { Set typeModifiers = ((CodeTypeElement) type).getModifiers(); Modifier visibility = ElementUtils.getVisibility(type.getModifiers()); typeModifiers.clear(); if (visibility != null) { typeModifiers.add(visibility); } typeModifiers.add(Modifier.STATIC); typeModifiers.add(Modifier.FINAL); clazz.add(type); } } List children = node.getNodeDeclaringChildren(); if (node.getDeclaringNode() == null && children.size() > 0) { clazz.add(createGetFactories(node)); } } private Element createNodeFactoryConstructor(NodeData node) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE), null, factoryClassName(node)); CodeTreeBuilder builder = method.createBuilder(); builder.startStatement(); builder.startCall("super"); // node type builder.typeLiteral(node.getNodeType()); // execution signature builder.startGroup(); if (node.getChildExecutions().isEmpty()) { builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY); } else { builder.startNewArray(new ArrayCodeTypeMirror(context.getType(Class.class)), null); for (NodeExecutionData execution : node.getChildExecutions()) { builder.typeLiteral(execution.getNodeType()); } builder.end(); } builder.end(); // node signatures builder.startGroup(); builder.startNewArray(new ArrayCodeTypeMirror(new ArrayCodeTypeMirror(context.getType(Class.class))), null); List constructors = findUserConstructors(generatedNode.asType()); for (ExecutableElement constructor : constructors) { builder.startGroup(); if (constructor.getParameters().isEmpty()) { builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY); } else { builder.startNewArray(new ArrayCodeTypeMirror(context.getType(Class.class)), null); for (VariableElement var : constructor.getParameters()) { builder.typeLiteral(var.asType()); } builder.end(); } builder.end(); } builder.end(); builder.end(); builder.end().end().end(); return method; } private CodeExecutableElement createCreateNodeMethod(NodeData node) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode"); CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Object.class), "arguments"); method.setVarArgs(true); method.addParameter(arguments); CodeTreeBuilder builder = method.createBuilder(); List signatures = findUserConstructors(generatedNode.asType()); boolean ifStarted = false; for (ExecutableElement element : signatures) { ifStarted = builder.startIf(ifStarted); builder.string("arguments.length == " + element.getParameters().size()); int index = 0; for (VariableElement param : element.getParameters()) { if (ElementUtils.isObject(param.asType())) { continue; } builder.string(" && "); if (!param.asType().getKind().isPrimitive()) { builder.string("(arguments[" + index + "] == null || "); } builder.string("arguments[" + index + "] instanceof "); builder.type(ElementUtils.boxType(getContext(), param.asType())); if (!param.asType().getKind().isPrimitive()) { builder.string(")"); } index++; } builder.end(); builder.startBlock(); builder.startReturn().startCall("create"); index = 0; for (VariableElement param : element.getParameters()) { builder.startGroup(); if (!ElementUtils.isObject(param.asType())) { builder.string("(").type(param.asType()).string(") "); } builder.string("arguments[").string(String.valueOf(index)).string("]"); builder.end(); index++; } builder.end().end(); builder.end(); // block } builder.startElseBlock(); builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)); builder.doubleQuote("Invalid create signature."); builder.end().end(); builder.end(); // else block return method; } private ExecutableElement createGetInstanceMethod(NodeData node, Modifier visibility) { TypeElement nodeFactoryType = ElementUtils.fromTypeMirror(getContext().getType(NodeFactory.class)); TypeMirror returnType = ElementUtils.getDeclaredType(nodeFactoryType, node.getNodeType()); CodeExecutableElement method = new CodeExecutableElement(modifiers(), returnType, "getInstance"); if (visibility != null) { method.getModifiers().add(visibility); } method.getModifiers().add(Modifier.STATIC); String varName = instanceVarName(node); CodeTreeBuilder builder = method.createBuilder(); builder.startIf(); builder.string(varName).string(" == null"); builder.end().startBlock(); builder.startStatement(); builder.string(varName); builder.string(" = "); builder.startNew(factoryClassName(node)).end(); builder.end(); builder.end(); builder.startReturn().string(varName).end(); return method; } private String instanceVarName(NodeData node) { if (node.getDeclaringNode() != null) { return ElementUtils.firstLetterLowerCase(factoryClassName(node)) + "Instance"; } else { return "instance"; } } private CodeVariableElement createInstanceConstant(NodeData node, TypeMirror factoryType) { String varName = instanceVarName(node); CodeVariableElement var = new CodeVariableElement(modifiers(), factoryType, varName); var.getModifiers().add(Modifier.PRIVATE); var.getModifiers().add(Modifier.STATIC); return var; } private ExecutableElement createGetFactories(NodeData node) { List children = node.getNodeDeclaringChildren(); if (node.needsFactory()) { children.add(node); } List nodeTypesList = new ArrayList<>(); TypeMirror prev = null; boolean allSame = true; for (NodeData child : children) { nodeTypesList.add(child.getNodeType()); if (prev != null && !ElementUtils.typeEquals(child.getNodeType(), prev)) { allSame = false; } prev = child.getNodeType(); } TypeMirror commonNodeSuperType = ElementUtils.getCommonSuperType(getContext(), nodeTypesList.toArray(new TypeMirror[nodeTypesList.size()])); Types types = getContext().getEnvironment().getTypeUtils(); TypeMirror factoryType = getContext().getType(NodeFactory.class); TypeMirror baseType; if (allSame) { baseType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(factoryType), commonNodeSuperType); } else { baseType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(factoryType), types.getWildcardType(commonNodeSuperType, null)); } TypeMirror listType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(getContext().getType(List.class)), baseType); CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), listType, "getFactories"); CodeTreeBuilder builder = method.createBuilder(); builder.startReturn(); builder.startStaticCall(getContext().getType(Arrays.class), "asList"); for (NodeData child : children) { builder.startGroup(); NodeData childNode = child; List factories = new ArrayList<>(); while (childNode.getDeclaringNode() != null) { factories.add(childNode); childNode = childNode.getDeclaringNode(); } Collections.reverse(factories); for (NodeData nodeData : factories) { builder.string(factoryClassName(nodeData)).string("."); } builder.string("getInstance()"); builder.end(); } builder.end(); builder.end(); return method; } private void createFactoryMethods(NodeData node, CodeTypeElement clazz, Modifier createVisibility) { List constructors = findUserConstructors(generatedNode.asType()); for (ExecutableElement constructor : constructors) { clazz.add(createCreateMethod(node, createVisibility, constructor)); } } private CodeExecutableElement createCreateMethod(NodeData node, Modifier visibility, ExecutableElement constructor) { CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), constructor); method.setSimpleName(CodeNames.of("create")); method.getModifiers().clear(); if (visibility != null) { method.getModifiers().add(visibility); } method.getModifiers().add(Modifier.STATIC); method.setReturnType(node.getNodeType()); CodeTreeBuilder body = method.createBuilder(); body.startReturn(); if (node.getSpecializations().isEmpty()) { body.nullLiteral(); } else { body.startCall(nodeSpecializationClassName(node.getSpecializations().get(0)), FACTORY_METHOD_NAME); for (VariableElement var : method.getParameters()) { body.string(var.getSimpleName().toString()); } body.end(); } body.end(); return method; } } private class NodeBaseFactory extends AbstractClassElementFactory { @Override protected CodeTypeElement create(SpecializationData specialization) { NodeData node = specialization.getNode(); CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, ABSTRACT, STATIC), baseClassName(node), node.getNodeType(), false); clazz.getImplements().add(context.getTruffleTypes().getDslNode()); for (NodeChildData child : node.getChildren()) { clazz.add(createChildField(child)); if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) { ExecutableElement getter = (ExecutableElement) child.getAccessElement(); CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), getter); method.getModifiers().remove(Modifier.ABSTRACT); CodeTreeBuilder builder = method.createBuilder(); builder.startReturn().string("this.").string(child.getName()).end(); clazz.add(method); } } for (NodeFieldData field : node.getFields()) { if (!field.isGenerated()) { continue; } clazz.add(new CodeVariableElement(modifiers(PROTECTED, FINAL), field.getType(), field.getName())); if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) { CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), field.getGetter()); method.getModifiers().remove(Modifier.ABSTRACT); method.createBuilder().startReturn().string("this.").string(field.getName()).end(); clazz.add(method); } } for (String assumption : node.getAssumptions()) { clazz.add(createAssumptionField(assumption)); } createConstructors(node, clazz); return clazz; } @Override protected void createChildren(SpecializationData specialization) { NodeData node = specialization.getNode(); CodeTypeElement clazz = getElement(); SpecializationGroup rootGroup = createSpecializationGroups(node); if (node.needsRewrites(context)) { if (node.isPolymorphic(context)) { CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0"); var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation())); clazz.add(var); CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization()); clazz.add(genericCachedExecute); } for (CodeExecutableElement method : createImplicitChildrenAccessors()) { clazz.add(method); } clazz.add(createInfoMessage(node)); clazz.add(createMonomorphicRewrite()); clazz.add(createCreateSpecializationMethod(node, rootGroup)); } clazz.add(createAdoptChildren0()); clazz.add(createGetMetadata0(true)); clazz.add(createUpdateTypes0()); clazz.add(createGetNext()); } private Element createGetNext() { CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), context.getType(Node.class), "getNext0"); CodeTreeBuilder builder = method.createBuilder(); NodeData node = getModel().getNode(); if (node.isPolymorphic(context)) { builder.startReturn().string("next0").end(); } else { builder.returnNull(); } return method; } protected final CodeExecutableElement createUpdateTypes0() { ArrayType classArray = new ArrayCodeTypeMirror(context.getType(Class.class)); CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(void.class), "updateTypes0"); method.getParameters().add(new CodeVariableElement(classArray, "types")); if (getModel().isPolymorphic()) { CodeTreeBuilder builder = method.createBuilder(); int index = 0; for (NodeExecutionData execution : getModel().getNode().getChildExecutions()) { String fieldName = polymorphicTypeName(execution); builder.startStatement(); builder.string(fieldName).string(" = ").string("types[").string(String.valueOf(index)).string("]"); builder.end(); index++; } } return method; } protected final CodeExecutableElement createGetMetadata0(boolean empty) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getDslMetadata(), "getMetadata0"); if (empty) { method.createBuilder().startReturn().staticReference(context.getTruffleTypes().getDslMetadata(), "NONE").end(); } else { method.createBuilder().startReturn().string(METADATA_FIELD_NAME).end(); } return method; } private CodeExecutableElement createAdoptChildren0() { CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), context.getType(void.class), "adoptChildren0"); method.getParameters().add(new CodeVariableElement(context.getTruffleTypes().getNode(), "other")); method.getParameters().add(new CodeVariableElement(context.getTruffleTypes().getNode(), "newNext")); NodeData node = getModel().getNode(); CodeTreeBuilder builder = method.createBuilder(); List executions = node.getChildExecutions(); if (executions.size() > 0) { builder.startIf().string("other == null").end().startBlock(); for (NodeExecutionData execution : executions) { builder.startStatement().tree(createAccessChild(execution, "this")).string(" = null").end(); } builder.end().startElseBlock(); String access; if (executions.size() > 1) { builder.declaration(baseClassName(node), "otherCast", builder.create().cast(baseClassName(node)).string("other")); access = "otherCast"; } else { assert executions.size() == 1; access = "((" + baseClassName(node) + ") other)"; } for (NodeExecutionData execution : executions) { builder.startStatement().tree(createAccessChild(execution, "this")).string(" = ").tree(createAccessChild(execution, access)).end(); } builder.end(); } if (getModel().getNode().isPolymorphic(context)) { builder.startIf().string("newNext == null").end().startBlock(); builder.statement("this.next0 = null"); builder.end().startElseBlock(); builder.statement("this.next0 = (" + baseClassName(getModel().getNode()) + ") newNext"); builder.end(); } return method; } private List createImplicitChildrenAccessors() { NodeData node = getModel().getNode(); List> prototype = Collections.nCopies(node.getGenericSpecialization().getParameters().size(), null); List> expectTypes = new ArrayList<>(prototype); for (ExecutableTypeData executableType : node.getExecutableTypes()) { for (int i = 0; i < executableType.getEvaluatedCount(); i++) { Parameter parameter = executableType.getSignatureParameter(i); if (i >= expectTypes.size()) { break; } Set types = expectTypes.get(i); if (types == null) { types = new TreeSet<>(); expectTypes.set(i, types); } types.add(parameter.getTypeSystemType()); } } List methods = new ArrayList<>(); List> visitedList = new ArrayList<>(prototype); for (SpecializationData spec : node.getSpecializations()) { int signatureIndex = -1; for (Parameter param : spec.getParameters()) { if (!param.getSpecification().isSignature()) { continue; } signatureIndex++; Set visitedTypeData = visitedList.get(signatureIndex); if (visitedTypeData == null) { visitedTypeData = new TreeSet<>(); visitedList.set(signatureIndex, visitedTypeData); } if (visitedTypeData.contains(param.getTypeSystemType())) { continue; } visitedTypeData.add(param.getTypeSystemType()); Set expect = expectTypes.get(signatureIndex); if (expect == null) { expect = Collections.emptySet(); } methods.addAll(createExecuteChilds(param, expect)); } } return methods; } private CodeTree truffleBooleanOption(CodeTreeBuilder parent, String name) { CodeTreeBuilder builder = parent.create(); builder.staticReference(getContext().getTruffleTypes().getTruffleOptions(), name); return builder.getRoot(); } private Element createInfoMessage(NodeData node) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), CREATE_INFO); method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message")); addInternalValueParameters(method, node.getGenericSpecialization(), false, false, false); CodeTreeBuilder builder = method.createBuilder(); builder.startIf().tree(truffleBooleanOption(builder, TruffleTypes.OPTION_DETAILED_REWRITE_REASONS)).end(); builder.startBlock(); builder.startStatement().string("StringBuilder builder = new StringBuilder(message)").end(); builder.startStatement().startCall("builder", "append").doubleQuote(" (").end().end(); String sep = null; for (Parameter parameter : node.getGenericSpecialization().getSignatureParameters()) { builder.startStatement(); builder.string("builder"); if (sep != null) { builder.startCall(".append").doubleQuote(sep).end(); } builder.startCall(".append").doubleQuote(parameter.getLocalName()).end(); builder.startCall(".append").doubleQuote(" = ").end(); builder.startCall(".append").string(parameter.getLocalName()).end(); builder.end(); if (!ElementUtils.isPrimitive(parameter.getType())) { builder.startIf().string(parameter.getLocalName() + " != null").end(); builder.startBlock(); } builder.startStatement(); if (ElementUtils.isPrimitive(parameter.getType())) { builder.startCall("builder.append").doubleQuote(" (" + ElementUtils.getSimpleName(parameter.getType()) + ")").end(); } else { builder.startCall("builder.append").doubleQuote(" (").end(); builder.startCall(".append").string(parameter.getLocalName() + ".getClass().getSimpleName()").end(); builder.startCall(".append").doubleQuote(")").end(); } builder.end(); if (!ElementUtils.isPrimitive(parameter.getType())) { builder.end(); } sep = ", "; } builder.startStatement().startCall("builder", "append").doubleQuote(")").end().end(); builder.startReturn().string("builder.toString()").end(); builder.end(); builder.startElseBlock(); builder.startReturn().string("message").end(); builder.end(); return method; } private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) { CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED); addInternalValueParameters(cachedExecute, polymorph, true, false, false); ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0); boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext()); if (sourceThrowsUnexpected && sourceExecutableType.getType().equals(node.getGenericSpecialization().getReturnType().getTypeSystemType())) { sourceThrowsUnexpected = false; } if (sourceThrowsUnexpected) { cachedExecute.getThrownTypes().add(getContext().getType(UnexpectedResultException.class)); } return cachedExecute; } private void createConstructors(NodeData node, CodeTypeElement clazz) { List constructors = findUserConstructors(node.getNodeType()); ExecutableElement sourceSectionConstructor = null; if (constructors.isEmpty()) { clazz.add(createUserConstructor(clazz, null)); } else { for (ExecutableElement constructor : constructors) { clazz.add(createUserConstructor(clazz, constructor)); if (NodeParser.isSourceSectionConstructor(context, constructor)) { sourceSectionConstructor = constructor; } } } if (node.needsRewrites(getContext())) { ExecutableElement copyConstructor = findCopyConstructor(node.getNodeType()); clazz.add(createCopyConstructor(clazz, copyConstructor, sourceSectionConstructor)); } } private CodeExecutableElement createUserConstructor(CodeTypeElement type, ExecutableElement superConstructor) { CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString()); CodeTreeBuilder builder = method.createBuilder(); NodeData node = getModel().getNode(); if (superConstructor != null) { for (VariableElement param : superConstructor.getParameters()) { method.getParameters().add(CodeVariableElement.clone(param)); } } if (superConstructor != null) { builder.startStatement().startSuperCall(); for (VariableElement param : superConstructor.getParameters()) { builder.string(param.getSimpleName().toString()); } builder.end().end(); } for (VariableElement var : type.getFields()) { if (var.getModifiers().contains(STATIC)) { continue; } NodeChildData child = node.findChild(var.getSimpleName().toString()); if (child != null) { method.getParameters().add(new CodeVariableElement(child.getOriginalType(), child.getName())); } else { method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString())); } builder.startStatement(); String fieldName = var.getSimpleName().toString(); CodeTree init = createStaticCast(builder, child, fieldName); builder.string("this.").string(fieldName).string(" = ").tree(init); builder.end(); } return method; } private CodeTree createStaticCast(CodeTreeBuilder parent, NodeChildData child, String fieldName) { NodeData parentNode = getModel().getNode(); if (child != null) { CreateCastData createCast = parentNode.findCast(child.getName()); if (createCast != null) { return createTemplateMethodCall(parent, null, parentNode.getGenericSpecialization(), createCast, null, fieldName); } } return CodeTreeBuilder.singleString(fieldName); } private CodeExecutableElement createCopyConstructor(CodeTypeElement type, ExecutableElement superConstructor, ExecutableElement sourceSectionConstructor) { CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString()); CodeTreeBuilder builder = method.createBuilder(); method.getParameters().add(new CodeVariableElement(type.asType(), "copy")); if (superConstructor != null) { builder.startStatement().startSuperCall().string("copy").end().end(); } else if (sourceSectionConstructor != null) { builder.startStatement().startSuperCall().string("copy.getSourceSection()").end().end(); } for (VariableElement var : type.getFields()) { if (var.getModifiers().contains(STATIC) || !var.getModifiers().contains(FINAL)) { continue; } final String varName = var.getSimpleName().toString(); final TypeMirror varType = var.asType(); if (ElementUtils.isAssignable(varType, getContext().getTruffleTypes().getNodeArray())) { CodeTree size = builder.create().string("copy.", varName, ".length").getRoot(); builder.startStatement().string("this.").string(varName).string(" = ").startNewArray((ArrayType) varType, size).end().end(); } else { builder.startStatement().string("this.", varName, " = copy.", varName).end(); } } return method; } private CodeVariableElement createAssumptionField(String assumption) { CodeVariableElement var = new CodeVariableElement(getContext().getTruffleTypes().getAssumption(), assumption); var.getModifiers().add(Modifier.FINAL); return var; } private CodeVariableElement createChildField(NodeChildData child) { TypeMirror type = child.getNodeType(); CodeVariableElement var = new CodeVariableElement(type, child.getName()); var.getModifiers().add(Modifier.PROTECTED); DeclaredType annotationType; if (child.getCardinality() == Cardinality.MANY) { var.getModifiers().add(Modifier.FINAL); annotationType = getContext().getTruffleTypes().getChildrenAnnotation(); } else { annotationType = getContext().getTruffleTypes().getChildAnnotation(); } var.getAnnotationMirrors().add(new CodeAnnotationMirror(annotationType)); return var; } private SpecializationGroup createSpecializationGroups(final NodeData node) { List specializations = node.getSpecializations(); List filteredSpecializations = new ArrayList<>(); for (SpecializationData current : specializations) { if (current.isUninitialized() || current.isPolymorphic() || !current.isReachable()) { continue; } filteredSpecializations.add(current); } return SpecializationGroup.create(filteredSpecializations); } protected final CodeExecutableElement createExecuteUninitialized() { NodeData node = getModel().getNode(); SpecializationData generic = node.getGenericSpecialization(); CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED); addInternalValueParameters(method, generic, true, false, false); CodeTreeBuilder builder = method.createBuilder(); boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); CodeTreeBuilder createSpecializationCall = builder.create(); createSpecializationCall.startCall(SPECIALIZE); addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); createSpecializationCall.end(); builder.declaration(baseClassName(node), "newNode", createSpecializationCall); if (generic.isReachable()) { builder.startIf().string("newNode == null").end().startBlock(); builder.startIf().startStaticCall(context.getTruffleTypes().getCompilerDirectives(), "inInterpreter").end().end().startBlock(); builder.statement("containsFallback = true"); builder.end(); builder.tree(createGenericInvoke(builder, generic, generic)); builder.end(); builder.startElseBlock(); builder.tree(createDeoptimize(builder)); builder.end(); } builder.startReturn(); builder.startStaticCall(context.getTruffleTypes().getDslShare(), "rewriteUninitialized").string("this").string("newNode").end(); builder.string(".").startCall(EXECUTE_CHAINED); addInternalValueParameterNames(builder, generic, generic, null, true, false, null); builder.end(); builder.end(); if (generic.isReachable()) { builder.end(); } return method; } private CodeTree createInfoCall(CodeTreeBuilder parent, SpecializationData specialization, String reason) { CodeTreeBuilder builder = parent.create(); builder.startCall(CREATE_INFO).string(reason); addInternalValueParameterNames(builder, specialization, specialization, null, false, false, null); builder.end(); return builder.getRoot(); } private CodeExecutableElement createMonomorphicRewrite() { NodeData node = getModel().getNode(); SpecializationData generic = node.getGenericSpecialization(); CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE); addInternalValueParameters(method, generic, true, false, false); method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); CodeTreeBuilder builder = method.createBuilder(); builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end(); String baseClassName = baseClassName(getModel().getNode()); CodeTreeBuilder createSpecializationCall = builder.create(); createSpecializationCall.startCall(SPECIALIZE); addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); createSpecializationCall.end(); builder.declaration(baseClassName, "newNode", createSpecializationCall); builder.startIf().string("newNode == null").end().startBlock(); builder.startStatement(); String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization()); builder.string("newNode = ").startNew(uninitializedName).string("this").end(); builder.end(); if (node.isFallbackReachable()) { builder.startStatement().string("((", uninitializedName, ") newNode).containsFallback = true").end(); } builder.end(); builder.startStatement(); builder.type(getContext().getType(String.class)).string(" message = ").tree(createInfoCall(builder, generic, "reason")); builder.end(); builder.declaration(baseClassName, "returnNode", builder.create().startStaticCall(context.getTruffleTypes().getDslShare(), DSLSHARE_REWRITE).string("this").string("newNode").string("message").end().getRoot()); builder.startIf().string("returnNode == null").end().startBlock(); builder.tree(createRewritePolymorphic(builder, node, "this")); builder.end(); builder.startReturn(); builder.startCall("returnNode", EXECUTE_CHAINED); addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, false, null); builder.end(); builder.end(); return method; } private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) { String polyClassName = nodePolymorphicClassName(node); CodeTreeBuilder builder = parent.create(); builder.startStatement().string("returnNode = "); builder.startStaticCall(context.getTruffleTypes().getDslShare(), DSLSHARE_REWRITE_TO_POLYMORHPIC); builder.string("this"); builder.tree(builder.create().startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string(currentNode).end().getRoot()); builder.tree(builder.create().startNew(polyClassName).string(currentNode).end().getRoot()); builder.startGroup().cast(baseClassName(node)).startCall("copy").end().end(); builder.string("newNode"); builder.string("message"); builder.end(); builder.end(); return builder.getRoot(); } private CodeExecutableElement createCreateSpecializationMethod(NodeData node, SpecializationGroup group) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), new GeneratedTypeMirror(ElementUtils.getPackageName(node.getTemplateType()), baseClassName(node)), SPECIALIZE); final boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); if (!needsFrame) { method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getTruffleBoundary())); } addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, !needsFrame, false); final CodeTreeBuilder builder = method.createBuilder(); builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, new CodeBlock() { public CodeTree create(CodeTreeBuilder b, SpecializationData current) { return createCreateSpecializationMethodBody0(builder, current, needsFrame); } }, null, false, true, false, true)); emitUnreachableSpecializations(builder, node); return method; } protected CodeTree createCreateSpecializationMethodBody0(CodeTreeBuilder parent, SpecializationData current, boolean useDeoptimize) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (current.isGeneric()) { builder.startReturn().nullLiteral().end(); } else { String className = nodeSpecializationClassName(current); if (!current.getExcludedBy().isEmpty()) { builder.startIf().string("!").startStaticCall(context.getTruffleTypes().getDslShare(), "isExcluded"); builder.string("this").string(nodeSpecializationClassName(current), ".", METADATA_FIELD_NAME).end().end(); builder.startBlock(); } if (current.getNode().getGenericSpecialization().isReachable() && useDeoptimize) { builder.tree(createDeoptimize(builder)); } builder.startReturn(); builder.cast(baseClassName(getModel().getNode())); builder.startGroup().startCall(className, FACTORY_METHOD_NAME).string("this"); for (Parameter param : current.getSignatureParameters()) { NodeChildData child = param.getSpecification().getExecution().getChild(); List types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); if (types.size() > 1) { builder.string(implicitTypeName(param)); } } builder.end().end(); builder.end(); if (!current.getExcludedBy().isEmpty()) { builder.end(); } } return builder.getRoot(); } private void emitUnreachableSpecializations(final CodeTreeBuilder builder, NodeData node) { for (SpecializationData current : node.getSpecializations()) { if (current.isReachable()) { continue; } builder.string("// unreachable ").string(current.getId()).newLine(); } } protected CodeTree createExecuteTree(CodeTreeBuilder outerParent, final SpecializationData source, final SpecializationGroup group, final CodeBlock guardedblock, final CodeTree elseBlock, boolean forceElse, final boolean emitAssumptions, final boolean typedCasts, final boolean castForGuardsOnly) { return guard(outerParent, source, group, new CodeBlock() { public CodeTree create(CodeTreeBuilder parent, Integer ifCount) { CodeTreeBuilder builder = parent.create(); if (group.getSpecialization() != null) { builder.tree(guardedblock.create(builder, group.getSpecialization())); assert group.getChildren().isEmpty() : "missed a specialization"; } else { for (SpecializationGroup childGroup : group.getChildren()) { builder.tree(createExecuteTree(builder, source, childGroup, guardedblock, null, false, emitAssumptions, typedCasts, castForGuardsOnly)); } } return builder.getRoot(); } }, elseBlock, forceElse, emitAssumptions, typedCasts, castForGuardsOnly); } private CodeTree guard(CodeTreeBuilder parent, SpecializationData source, SpecializationGroup group, CodeBlock bodyBlock, CodeTree elseBlock, boolean forceElse, boolean emitAssumptions, boolean typedCasts, boolean castForGuardsOnly) { CodeTreeBuilder builder = parent.create(); int ifCount = emitGuards(builder, source, group, emitAssumptions, typedCasts, castForGuardsOnly); if (isReachableGroup(group, ifCount)) { builder.tree(bodyBlock.create(builder, ifCount)); } builder.end(ifCount); if (elseBlock != null) { if (ifCount > 0 || forceElse) { builder.tree(elseBlock); } } return builder.getRoot(); } private boolean isReachableGroup(SpecializationGroup group, int ifCount) { if (ifCount != 0) { return true; } SpecializationGroup previous = group.getPreviousGroup(); if (previous == null || previous.findElseConnectableGuards().isEmpty()) { return true; } /* * Hacky else case. In this case the specialization is not reachable due to previous * else branch. This is only true if the minimum state is not checked. */ if (previous.getGuards().size() == 1 && previous.getTypeGuards().isEmpty() && previous.getAssumptions().isEmpty() && (previous.getParent() == null || previous.getMaxSpecializationIndex() != previous.getParent().getMaxSpecializationIndex())) { return false; } return true; } private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean emitAssumptions, boolean typedCasts, boolean castForGuardsOnly) { NodeData node = source.getNode(); CodeTreeBuilder guardsBuilder = builder.create(); CodeTreeBuilder castBuilder = builder.create(); CodeTreeBuilder guardsCastBuilder = builder.create(); String guardsAnd = ""; String guardsCastAnd = ""; if (emitAssumptions) { for (String assumption : group.getAssumptions()) { guardsBuilder.string(guardsAnd); guardsBuilder.string("this"); guardsBuilder.string(".").string(assumption).string(".isValid()"); guardsAnd = " && "; } } for (TypeGuard typeGuard : group.getTypeGuards()) { Parameter valueParam = source.getSignatureParameter(typeGuard.getSignatureIndex()); if (valueParam == null) { /* * If used inside a execute evaluated method then the value param may not exist. * In that case we assume that the value is executed generic or of the current * specialization. */ if (group.getSpecialization() != null) { valueParam = group.getSpecialization().getSignatureParameter(typeGuard.getSignatureIndex()); } else { valueParam = node.getGenericSpecialization().getSignatureParameter(typeGuard.getSignatureIndex()); } } NodeExecutionData execution = valueParam.getSpecification().getExecution(); CodeTree implicitGuard = createTypeGuard(guardsBuilder, execution, valueParam, typeGuard.getType(), typedCasts); if (implicitGuard != null) { guardsBuilder.string(guardsAnd); guardsBuilder.tree(implicitGuard); guardsAnd = " && "; } CodeTree implicitGetType = null; if (castForGuardsOnly) { implicitGetType = createGetImplicitType(builder, execution, valueParam, typeGuard.getType()); } boolean performCast = true; if (castForGuardsOnly) { // if cast for guards we just cast if the type guard is used inside a guard. performCast = group.isTypeGuardUsedInAnyGuardBelow(context, source, typeGuard); } if (performCast) { CodeTree cast = createCast(castBuilder, execution, valueParam, typeGuard.getType(), typedCasts); if (cast != null) { castBuilder.tree(cast); } } if (implicitGetType != null) { castBuilder.tree(implicitGetType); } } List elseGuards = group.findElseConnectableGuards(); for (GuardExpression guard : group.getGuards()) { if (elseGuards.contains(guard)) { continue; } if (needsTypeGuard(source, group, guard)) { guardsCastBuilder.tree(createMethodGuard(builder, guardsCastAnd, source, guard)); guardsCastAnd = " && "; } else { guardsBuilder.tree(createMethodGuard(builder, guardsAnd, source, guard)); guardsAnd = " && "; } } int ifCount = startGuardIf(builder, guardsBuilder, 0, elseGuards); builder.tree(castBuilder.getRoot()); ifCount = startGuardIf(builder, guardsCastBuilder, ifCount, elseGuards); return ifCount; } private int startGuardIf(CodeTreeBuilder builder, CodeTreeBuilder conditionBuilder, int ifCount, List elseGuard) { int newIfCount = ifCount; if (!conditionBuilder.isEmpty()) { if (ifCount == 0 && !elseGuard.isEmpty()) { builder.startElseIf(); } else { builder.startIf(); } builder.tree(conditionBuilder.getRoot()); builder.end().startBlock(); newIfCount++; } else if (ifCount == 0 && !elseGuard.isEmpty()) { builder.startElseBlock(); newIfCount++; } return newIfCount; } private boolean needsTypeGuard(SpecializationData source, SpecializationGroup group, GuardExpression guard) { for (Parameter parameter : guard.getResolvedGuard().getParameters()) { if (!parameter.getSpecification().isSignature()) { continue; } int signatureIndex = source.getNode().getChildExecutions().indexOf(parameter.getSpecification().getExecution()); if (signatureIndex == -1) { continue; } TypeGuard typeGuard = group.findTypeGuard(signatureIndex); if (typeGuard != null) { TypeData requiredType = typeGuard.getType(); Parameter sourceParameter = source.findParameter(parameter.getLocalName()); if (sourceParameter == null) { sourceParameter = source.getNode().getGenericSpecialization().findParameter(parameter.getLocalName()); } if (ElementUtils.needsCastTo(sourceParameter.getType(), requiredType.getPrimitiveType())) { return true; } } } return false; } private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) { NodeData node = execution.getChild().getNodeData(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); TypeData sourceType = source.getTypeSystemType(); if (!sourceType.needsCastTo(targetType)) { return null; } builder.startGroup(); if (execution.isShortCircuit()) { Parameter shortCircuit = source.getPreviousParameter(); assert shortCircuit != null; builder.string("("); builder.string("!").string(valueName(shortCircuit)); builder.string(" || "); } String castMethodName; String castTypeName = null; List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); if (types.size() > 1) { castMethodName = TypeSystemCodeGenerator.isImplicitTypeMethodName(targetType); if (typedCasts) { castTypeName = implicitTypeName(source); } } else { castMethodName = TypeSystemCodeGenerator.isTypeMethodName(targetType); } startCallTypeSystemMethod(builder, node.getTypeSystem(), castMethodName); builder.string(valueName(source)); if (castTypeName != null) { builder.string(castTypeName); } builder.end().end(); // call if (execution.isShortCircuit()) { builder.string(")"); } builder.end(); // group return builder.getRoot(); } // TODO merge redundancies with #createTypeGuard private CodeTree createCast(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) { NodeData node = execution.getChild().getNodeData(); TypeData sourceType = source.getTypeSystemType(); if (!sourceType.needsCastTo(targetType)) { return null; } CodeTree condition = null; if (execution.isShortCircuit()) { Parameter shortCircuit = source.getPreviousParameter(); assert shortCircuit != null; condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); } String castMethodName; String castTypeName = null; List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); if (types.size() > 1) { castMethodName = TypeSystemCodeGenerator.asImplicitTypeMethodName(targetType); if (typedCasts) { castTypeName = implicitTypeName(source); } } else { castMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType); } List args = new ArrayList<>(); args.add(CodeTreeBuilder.singleString(valueName(source))); if (castTypeName != null) { args.add(CodeTreeBuilder.singleString(castTypeName)); } CodeTree cast = createCallTypeSystemMethod(parent, node, castMethodName, args.toArray(new CodeTree[0])); CodeTreeBuilder builder = parent.create(); builder.tree(createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, cast)); return builder.getRoot(); } private CodeTree createGetImplicitType(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType) { CodeTree condition = null; if (execution.isShortCircuit()) { Parameter shortCircuit = source.getPreviousParameter(); assert shortCircuit != null; condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); } CodeTreeBuilder builder = parent.create(); List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); if (types.size() > 1) { CodeTree castType = createCallTypeSystemMethod(parent, execution.getChild().getNodeData(), TypeSystemCodeGenerator.getImplicitClass(targetType), CodeTreeBuilder.singleString(valueName(source))); builder.tree(createLazyAssignment(builder, implicitTypeName(source), getContext().getType(Class.class), condition, castType)); } return builder.getRoot(); } private CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardExpression guard) { CodeTreeBuilder builder = parent.create(); builder.string(prefix); if (guard.isNegated()) { builder.string("!"); } builder.tree(createTemplateMethodCall(builder, null, source, guard.getResolvedGuard(), null)); return builder.getRoot(); } protected CodeTree createGenericInvoke(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (current.getMethod() == null) { emitEncounteredSynthetic(builder, current); } else { builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end(); } return encloseThrowsWithFallThrough(parent, current, builder.getRoot()); } private CodeTree encloseThrowsWithFallThrough(CodeTreeBuilder parent, SpecializationData current, CodeTree tree) { if (current.getExceptions().isEmpty()) { return tree; } CodeTreeBuilder builder = new CodeTreeBuilder(parent); builder.startTryBlock(); builder.tree(tree); for (SpecializationThrowsData exception : current.getExceptions()) { builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx"); builder.tree(createDeoptimize(builder)); builder.tree(createCallRewriteMonomorphic(builder, false, current.getNode().getGenericSpecialization().getReturnType().getTypeSystemType(), current, null, "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass()))); } builder.end(); return builder.getRoot(); } protected CodeTree createCastingExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable, ExecutableTypeData castExecutable) { TypeData type = executable.getType(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); NodeData node = specialization.getNode(); TypeData primaryType = castExecutable.getType(); boolean needsTry = castExecutable.hasUnexpectedValue(getContext()); boolean returnVoid = type.isVoid(); List executeParameters = new ArrayList<>(); for (Parameter sourceParameter : executable.getSignatureParameters()) { Parameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName()); if (targetParameter != null) { executeParameters.add(targetParameter); } } // execute names are enforced no cast String[] executeParameterNames = new String[executeParameters.size()]; for (int i = 0; i < executeParameterNames.length; i++) { executeParameterNames[i] = valueName(executeParameters.get(i)); } builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null)); boolean hasUnexpected = executable.hasUnexpectedValue(getContext()); CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null, executeParameterNames); if (needsTry) { if (!returnVoid) { builder.declaration(primaryType.getPrimitiveType(), "value"); } builder.startTryBlock(); if (returnVoid) { builder.statement(primaryExecuteCall); } else { builder.startStatement(); builder.string("value = "); builder.tree(primaryExecuteCall); builder.end(); } builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); if (returnVoid) { builder.string("// ignore").newLine(); } else { builder.startReturn(); builder.tree(createExpectExecutableType(node, specialization.getNode().getTypeSystem().getGenericTypeData(), hasUnexpected, executable.getType(), CodeTreeBuilder.singleString("ex.getResult()"))); builder.end(); } builder.end(); if (!returnVoid) { builder.startReturn(); builder.tree(createExpectExecutableType(node, castExecutable.getReturnType().getTypeSystemType(), hasUnexpected, executable.getType(), CodeTreeBuilder.singleString("value"))); builder.end(); } } else { if (returnVoid) { builder.statement(primaryExecuteCall); } else { builder.startReturn(); builder.tree(createExpectExecutableType(node, castExecutable.getReturnType().getTypeSystemType(), hasUnexpected, executable.getType(), primaryExecuteCall)); builder.end(); } } return builder.getRoot(); } protected CodeTree createExpectExecutableType(NodeData node, TypeData sourceType, boolean hasUnexpected, TypeData exepctedType, CodeTree value) { return createCastType(node.getTypeSystem(), sourceType, exepctedType, hasUnexpected, value); } protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List targetParameters, Parameter unexpectedParameter) { CodeTreeBuilder builder = parent.create(); for (Parameter targetParameter : targetParameters) { if (!targetParameter.getSpecification().isSignature()) { continue; } NodeExecutionData execution = targetParameter.getSpecification().getExecution(); CodeTree executionExpressions = createExecuteChild(builder, execution, sourceExecutable, targetParameter, unexpectedParameter); CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, specialization, sourceExecutable, targetParameter, execution.isShortCircuit(), unexpectedParameter); CodeTree shortCircuitTree = createShortCircuitTree(builder, unexpectedTree, specialization, targetParameter, unexpectedParameter); if (shortCircuitTree == executionExpressions) { if (containsNewLine(executionExpressions)) { builder.declaration(targetParameter.getType(), valueName(targetParameter)); builder.tree(shortCircuitTree); } else { builder.startStatement().type(targetParameter.getType()).string(" ").tree(shortCircuitTree).end(); } } else { builder.tree(shortCircuitTree); } } return builder.getRoot(); } private ExecutableTypeData resolveExecutableType(NodeExecutionData execution, TypeData type) { ExecutableTypeData targetExecutable = execution.getChild().findExecutableType(getContext(), type); if (targetExecutable == null) { targetExecutable = execution.getChild().findAnyGenericExecutableType(getContext()); } return targetExecutable; } private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, Parameter targetParameter, Parameter unexpectedParameter) { SpecializationData specialization = getModel(); if (specialization.isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { List possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter); if (possiblePolymorphicTypes.size() > 1) { CodeTreeBuilder builder = parent.create(); boolean elseIf = false; for (TypeData possiblePolymoprhicType : possiblePolymorphicTypes) { if (possiblePolymoprhicType.isGeneric()) { continue; } elseIf = builder.startIf(elseIf); Parameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName()); TypeData sourceType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null; builder.string(polymorphicTypeName(targetParameter.getSpecification().getExecution())).string(" == ").typeLiteral(possiblePolymoprhicType.getPrimitiveType()); builder.end().startBlock(); builder.startStatement(); builder.tree(createExecuteChildExpression(parent, execution, sourceType, new Parameter(targetParameter, possiblePolymoprhicType), unexpectedParameter, null)); builder.end(); builder.end(); } builder.startElseBlock(); builder.startStatement().tree(createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter)).end(); builder.end(); return builder.getRoot(); } } return createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter); } protected final List getImplicitTypeParameters(SpecializationData model) { List parameter = new ArrayList<>(); for (Parameter param : model.getSignatureParameters()) { NodeChildData child = param.getSpecification().getExecution().getChild(); List types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); if (types.size() > 1) { parameter.add(param); } } return parameter; } protected final List lookupPolymorphicTargetTypes(Parameter param) { SpecializationData specialization = getModel(); Set possiblePolymorphicTypes = new HashSet<>(); for (SpecializationData otherSpecialization : specialization.getNode().getSpecializations()) { if (!otherSpecialization.isSpecialized()) { continue; } Parameter otherParameter = otherSpecialization.findParameter(param.getLocalName()); if (otherParameter != null) { possiblePolymorphicTypes.add(otherParameter.getTypeSystemType()); } } List types = new ArrayList<>(possiblePolymorphicTypes); Collections.sort(types); return types; } private CodeTree createExecuteChildImplicit(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, Parameter param, Parameter unexpectedParameter) { CodeTreeBuilder builder = parent.create(); Parameter sourceParameter = sourceExecutable.findParameter(param.getLocalName()); String childExecuteName = createExecuteChildMethodName(param, sourceParameter != null); if (childExecuteName != null) { builder.string(valueName(param)); builder.string(" = "); builder.startCall(childExecuteName); for (Parameter parameters : sourceExecutable.getParameters()) { if (parameters.getSpecification().isSignature()) { continue; } builder.string(parameters.getLocalName()); } if (sourceParameter != null) { builder.string(valueNameEvaluated(sourceParameter)); } builder.string(implicitTypeName(param)); builder.end(); } else { List sourceTypes = execution.getChild().getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); TypeData expectType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null; if (sourceTypes.size() > 1) { builder.tree(createExecuteChildImplicitExpressions(parent, param, expectType)); } else { builder.tree(createExecuteChildExpression(parent, execution, expectType, param, unexpectedParameter, null)); } } return builder.getRoot(); } private String createExecuteChildMethodName(Parameter param, boolean expect) { NodeExecutionData execution = param.getSpecification().getExecution(); NodeChildData child = execution.getChild(); if (child.getExecuteWith().size() > 0) { return null; } List sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); if (sourceTypes.size() <= 1) { return null; } String prefix = expect ? "expect" : "execute"; String suffix = execution.getIndex() > -1 ? String.valueOf(execution.getIndex()) : ""; return prefix + ElementUtils.firstLetterUpperCase(child.getName()) + ElementUtils.firstLetterUpperCase(ElementUtils.getTypeId(param.getType())) + suffix; } private List createExecuteChilds(Parameter param, Set expectTypes) { CodeExecutableElement executeMethod = createExecuteChild(param, null); if (executeMethod == null) { return Collections.emptyList(); } List childs = new ArrayList<>(); childs.add(executeMethod); for (TypeData expectType : expectTypes) { CodeExecutableElement method = createExecuteChild(param, expectType); if (method != null) { childs.add(method); } } return childs; } private CodeExecutableElement createExecuteChild(Parameter param, TypeData expectType) { String childExecuteName = createExecuteChildMethodName(param, expectType != null); if (childExecuteName == null) { return null; } CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, expectType != null ? STATIC : FINAL), param.getType(), childExecuteName); method.getThrownTypes().add(getContext().getTruffleTypes().getUnexpectedValueException()); method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); if (expectType != null) { method.addParameter(new CodeVariableElement(expectType.getPrimitiveType(), valueNameEvaluated(param))); } method.addParameter(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param))); CodeTreeBuilder builder = method.createBuilder(); builder.declaration(param.getType(), valueName(param)); builder.tree(createExecuteChildImplicitExpressions(builder, param, expectType)); builder.startReturn().string(valueName(param)).end(); return method; } private CodeTree createExecuteChildImplicitExpressions(CodeTreeBuilder parent, Parameter targetParameter, TypeData expectType) { CodeTreeBuilder builder = parent.create(); NodeData node = getModel().getNode(); NodeExecutionData execution = targetParameter.getSpecification().getExecution(); List sourceTypes = node.getTypeSystem().lookupSourceTypes(targetParameter.getTypeSystemType()); boolean elseIf = false; int index = 0; for (TypeData sourceType : sourceTypes) { if (index < sourceTypes.size() - 1) { elseIf = builder.startIf(elseIf); builder.string(implicitTypeName(targetParameter)).string(" == ").typeLiteral(sourceType.getPrimitiveType()); builder.end(); builder.startBlock(); } else { builder.startElseBlock(); } ExecutableTypeData implictExecutableTypeData = execution.getChild().findExecutableType(getContext(), sourceType); if (implictExecutableTypeData == null) { /* * For children with executeWith.size() > 0 an executable type may not exist so * use the generic executable type which is guaranteed to exist. An expect call * is inserted automatically by #createExecuteExpression. */ implictExecutableTypeData = execution.getChild().getNodeData().findExecutableType(node.getTypeSystem().getGenericTypeData(), execution.getChild().getExecuteWith().size()); } ImplicitCastData cast = execution.getChild().getNodeData().getTypeSystem().lookupCast(sourceType, targetParameter.getTypeSystemType()); CodeTree execute = createExecuteChildExpression(builder, execution, expectType, targetParameter, null, cast); builder.statement(execute); builder.end(); index++; } return builder.getRoot(); } private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData execution, TypeData sourceParameterType, Parameter targetParameter, Parameter unexpectedParameter, ImplicitCastData cast) { // assignments: targetType <- castTargetType <- castSourceType <- sourceType TypeData sourceType = sourceParameterType; TypeData targetType = targetParameter.getTypeSystemType(); TypeData castSourceType = targetType; TypeData castTargetType = targetType; if (cast != null) { castSourceType = cast.getSourceType(); castTargetType = cast.getTargetType(); } CodeTree expression; if (sourceType == null) { ExecutableTypeData targetExecutable = resolveExecutableType(execution, castSourceType); expression = createExecuteChildExpression(parent, execution, targetExecutable, unexpectedParameter); sourceType = targetExecutable.getType(); } else { expression = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)); } // target = expectTargetType(implicitCast(expectCastSourceType(source))) TypeSystemData typeSystem = execution.getChild().getNodeData().getTypeSystem(); expression = createExpectType(typeSystem, sourceType, castSourceType, expression); expression = createImplicitCast(parent, typeSystem, cast, expression); expression = createExpectType(typeSystem, castTargetType, targetType, expression); CodeTreeBuilder builder = parent.create(); builder.string(valueName(targetParameter)); builder.string(" = "); builder.tree(expression); return builder.getRoot(); } private CodeTree createImplicitCast(CodeTreeBuilder parent, TypeSystemData typeSystem, ImplicitCastData cast, CodeTree expression) { if (cast == null) { return expression; } CodeTreeBuilder builder = parent.create(); startCallTypeSystemMethod(builder, typeSystem, cast.getMethodName()); builder.tree(expression); builder.end().end(); return builder.getRoot(); } private boolean containsNewLine(CodeTree tree) { if (tree.getCodeKind() == CodeTreeKind.NEW_LINE) { return true; } List enclosing = tree.getEnclosedElements(); if (enclosing != null) { for (CodeTree codeTree : enclosing) { if (containsNewLine(codeTree)) { return true; } } } return false; } private boolean hasUnexpected(Parameter sourceParameter, Parameter targetParameter, Parameter unexpectedParameter) { NodeExecutionData execution = targetParameter.getSpecification().getExecution(); if (getModel().isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { // check for other polymorphic types List polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter); if (polymorphicTargetTypes.size() > 1) { for (TypeData polymorphicTargetType : polymorphicTargetTypes) { if (hasUnexpectedType(execution, sourceParameter, polymorphicTargetType)) { return true; } } } } if (hasUnexpectedType(execution, sourceParameter, targetParameter.getTypeSystemType())) { return true; } return false; } private boolean hasUnexpectedType(NodeExecutionData execution, Parameter sourceParameter, TypeData targetType) { List implicitSourceTypes = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); for (TypeData implicitSourceType : implicitSourceTypes) { TypeData sourceType; ExecutableTypeData targetExecutable = resolveExecutableType(execution, implicitSourceType); if (sourceParameter != null) { sourceType = sourceParameter.getTypeSystemType(); } else { if (targetExecutable.hasUnexpectedValue(getContext())) { return true; } sourceType = targetExecutable.getType(); } ImplicitCastData cast = getModel().getNode().getTypeSystem().lookupCast(implicitSourceType, targetType); if (cast != null) { if (cast.getSourceType().needsCastTo(targetType)) { return true; } } if (sourceType.needsCastTo(targetType)) { return true; } } return false; } private CodeTree createCatchUnexpectedTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ExecutableTypeData currentExecutable, Parameter param, boolean shortCircuit, Parameter unexpectedParameter) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); Parameter sourceParameter = currentExecutable.findParameter(param.getLocalName()); boolean unexpected = hasUnexpected(sourceParameter, param, unexpectedParameter); if (!unexpected) { return body; } if (!shortCircuit) { builder.declaration(param.getType(), valueName(param)); } builder.startTryBlock(); if (containsNewLine(body)) { builder.tree(body); } else { builder.statement(body); } builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); SpecializationData generic = specialization.getNode().getGenericSpecialization(); Parameter genericParameter = generic.findParameter(param.getLocalName()); List genericParameters = generic.getParametersAfter(genericParameter); builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter)); if (specialization.isPolymorphic()) { builder.tree(createReturnOptimizeTypes(builder, currentExecutable, specialization, param)); } else { builder.tree(createCallRewriteMonomorphic(builder, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), specialization, param, "Expected " + param.getLocalName() + " instanceof " + ElementUtils.getSimpleName(param.getType()))); } builder.end(); // catch block return builder.getRoot(); } private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, ExecutableTypeData currentExecutable, SpecializationData specialization, Parameter param) { NodeData node = specialization.getNode(); SpecializationData polymorphic = node.getPolymorphicSpecialization(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); builder.startStatement().string(polymorphicTypeName(param.getSpecification().getExecution())).string(" = ").typeLiteral(getContext().getType(Object.class)).end(); builder.startReturn(); CodeTreeBuilder execute = new CodeTreeBuilder(builder); execute.startCall("next0", EXECUTE_CHAINED); addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, false, null); execute.end(); TypeData sourceType = polymorphic.getReturnType().getTypeSystemType(); builder.tree(createExpectExecutableType(node, sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot())); builder.end(); return builder.getRoot(); } private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, Parameter unexpectedParameter) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (targetExecution != null) { builder.tree(createAccessChild(targetExecution, null)); builder.string("."); } builder.startCall(targetExecutable.getMethodName()); // TODO this should be merged with #createTemplateMethodCall int index = 0; for (Parameter parameter : targetExecutable.getParameters()) { if (!parameter.getSpecification().isSignature()) { builder.string(parameter.getLocalName()); } else { if (index < targetExecution.getChild().getExecuteWith().size()) { NodeChildData child = targetExecution.getChild().getExecuteWith().get(index); ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName()); List specializationParams = getModel().findParameters(spec); if (specializationParams.isEmpty()) { builder.defaultValue(parameter.getType()); continue; } Parameter specializationParam = specializationParams.get(0); TypeData targetType = parameter.getTypeSystemType(); TypeData sourceType = specializationParam.getTypeSystemType(); String localName = specializationParam.getLocalName(); if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) { localName = "ex.getResult()"; sourceType = getModel().getNode().getTypeSystem().getGenericTypeData(); } CodeTree value = CodeTreeBuilder.singleString(localName); if (sourceType.needsCastTo(targetType)) { value = createCallTypeSystemMethod(builder, getModel().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value); } builder.tree(value); } else { builder.defaultValue(parameter.getType()); } index++; } } builder.end(); return builder.getRoot(); } private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, Parameter parameter, Parameter exceptionParam) { NodeExecutionData execution = parameter.getSpecification().getExecution(); if (execution == null || !execution.isShortCircuit()) { return body; } CodeTreeBuilder builder = new CodeTreeBuilder(parent); Parameter shortCircuitParam = specialization.getPreviousParam(parameter); builder.tree(createShortCircuitValue(builder, specialization, execution, shortCircuitParam, exceptionParam)); builder.declaration(parameter.getType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getType())); builder.startIf().string(shortCircuitParam.getLocalName()).end(); builder.startBlock(); if (containsNewLine(body)) { builder.tree(body); } else { builder.statement(body); } builder.end(); return builder.getRoot(); } private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeExecutionData execution, Parameter shortCircuitParam, Parameter exceptionParam) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); int shortCircuitIndex = 0; for (NodeExecutionData otherExectuion : specialization.getNode().getChildExecutions()) { if (otherExectuion.isShortCircuit()) { if (otherExectuion == execution) { break; } shortCircuitIndex++; } } builder.startStatement().type(shortCircuitParam.getType()).string(" ").string(valueName(shortCircuitParam)).string(" = "); ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex); builder.tree(createTemplateMethodCall(builder, null, specialization, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null)); builder.end(); // statement return builder.getRoot(); } protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, SpecializationData current, Parameter exceptionParam, String reason) { NodeData node = current.getNode(); SpecializationData generic = node.getGenericSpecialization(); CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); specializeCall.startCall(REWRITE); addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, false, null); specializeCall.doubleQuote(reason); specializeCall.end().end(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); builder.startReturn(); builder.tree(createExpectExecutableType(node, generic.getReturnType().getTypeSystemType(), hasUnexpected, returnType, specializeCall.getRoot())); builder.end(); return builder.getRoot(); } } private class PolymorphicNodeFactory extends SpecializedNodeFactory { public PolymorphicNodeFactory(CodeTypeElement nodeGen) { super(nodeGen); } @Override public CodeTypeElement create(SpecializationData polymorph) { NodeData node = polymorph.getNode(); TypeMirror baseType = node.getNodeType(); if (nodeGen != null) { baseType = nodeGen.asType(); } CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false); clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.POLYMORPHIC)); for (Parameter polymorphParameter : polymorph.getSignatureParameters()) { if (!polymorphParameter.getTypeSystemType().isGeneric()) { continue; } Set types = new HashSet<>(); for (SpecializationData specialization : node.getSpecializations()) { if (!specialization.isSpecialized()) { continue; } Parameter parameter = specialization.findParameter(polymorphParameter.getLocalName()); assert parameter != null; types.add(parameter.getTypeSystemType()); } } for (NodeExecutionData execution : getModel().getNode().getChildExecutions()) { String fieldName = polymorphicTypeName(execution); CodeVariableElement var = new CodeVariableElement(modifiers(PRIVATE), getContext().getType(Class.class), fieldName); var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getCompilationFinal())); clazz.add(var); } return clazz; } @Override protected void createChildren(SpecializationData specialization) { CodeTypeElement clazz = getElement(); createConstructors(clazz); createExecuteMethods(specialization); clazz.add(createUpdateTypes0()); createCachedExecuteMethods(specialization); } } private class SpecializedNodeFactory extends NodeBaseFactory { protected final CodeTypeElement nodeGen; public SpecializedNodeFactory(CodeTypeElement nodeGen) { this.nodeGen = nodeGen; } @Override public CodeTypeElement create(SpecializationData specialization) { NodeData node = specialization.getNode(); TypeMirror baseType = node.getNodeType(); if (nodeGen != null) { baseType = nodeGen.asType(); } CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false); if (specialization.isSpecialized() || specialization.isUninitialized()) { clazz.add(createGetMetadata0(false)); clazz.add(createMetadataLiteral()); } NodeCost cost; if (specialization.isGeneric()) { cost = NodeCost.MEGAMORPHIC; } else if (specialization.isUninitialized()) { cost = NodeCost.UNINITIALIZED; } else if (specialization.isPolymorphic()) { cost = NodeCost.POLYMORPHIC; } else if (specialization.isSpecialized()) { cost = NodeCost.MONOMORPHIC; } else { throw new AssertionError(); } clazz.getAnnotationMirrors().add(createNodeInfo(node, cost)); if (specialization.isUninitialized() && node.getGenericSpecialization().isReachable()) { clazz.add(createUninitializedGetCostOverride()); } return clazz; } private Element createUninitializedGetCostOverride() { TypeMirror returnType = context.getTruffleTypes().getNodeCost(); CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getCost"); CodeTreeBuilder builder = method.createBuilder(); builder.startIf().string(CONTAINS_FALLBACK).end().startBlock(); builder.startReturn().staticReference(returnType, "MONOMORPHIC").end(); builder.end(); builder.startReturn().string("super.getCost()").end(); return method; } private CodeVariableElement createMetadataLiteral() { CodeVariableElement includes = new CodeVariableElement(modifiers(PRIVATE, STATIC, FINAL), context.getTruffleTypes().getDslMetadata(), METADATA_FIELD_NAME); CodeTreeBuilder builder = includes.createInitBuilder(); SpecializationData specialization = getModel(); NodeData node = specialization.getNode(); Set contains = specialization.getContains(); if (specialization.isUninitialized()) { contains = new HashSet<>(); SpecializationData polymorphic = node.getPolymorphicSpecialization(); if (polymorphic != null) { contains.addAll(polymorphic.getContains()); } SpecializationData generic = node.getGenericSpecialization(); if (generic != null) { contains.addAll(generic.getContains()); } } builder.startNew(context.getTruffleTypes().getDslMetadata()); builder.startGroup().string(nodeSpecializationClassName(getModel()), ".class").end(); builder.tree(createSpecializationListLiteral(builder, contains)); builder.tree(createSpecializationListLiteral(builder, getModel().getExcludedBy())); builder.tree(createSpecializationTypeLiteral(builder, SpecializationData.getSignatureTypes(getModel()))); builder.string("0").string("0"); builder.end(); return includes; } private CodeTree createSpecializationTypeLiteral(CodeTreeBuilder parent, List list) { ArrayType classArray = new ArrayCodeTypeMirror(context.getType(Class.class)); CodeTreeBuilder builder = parent.create(); if (list.isEmpty()) { builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY); } else { builder.startNewArray(classArray, null); for (TypeMirror type : list) { builder.typeLiteral(type); } builder.end(); } return builder.getRoot(); } private CodeTree createSpecializationListLiteral(CodeTreeBuilder parent, Set list) { ArrayType classArray = new ArrayCodeTypeMirror(context.getType(Class.class)); CodeTreeBuilder builder = parent.create(); if (list.isEmpty()) { builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY); } else { builder.startNewArray(classArray, null); for (SpecializationData specialization : list) { SpecializationData s = specialization; if (s.isGeneric() || s.isPolymorphic()) { s = getModel().getNode().getUninitializedSpecialization(); } builder.startGroup().string(nodeSpecializationClassName(s)).string(".class").end(); } builder.end(); } return builder.getRoot(); } protected CodeAnnotationMirror createNodeInfo(NodeData node, NodeCost cost) { String shortName = node.getShortName(); CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation()); if (shortName != null) { nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName)); } DeclaredType nodeinfoCost = getContext().getTruffleTypes().getNodeCost(); VariableElement varKind = ElementUtils.findVariableElement(nodeinfoCost, cost.name()); nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("cost"), new CodeAnnotationValue(varKind)); return nodeInfoMirror; } @Override protected void createChildren(SpecializationData specialization) { CodeTypeElement clazz = getElement(); createConstructors(clazz); createExecuteMethods(specialization); createCachedExecuteMethods(specialization); if (specialization.isUninitialized()) { if (specialization.getNode().isFallbackReachable()) { CodeVariableElement var = new CodeVariableElement(modifiers(Modifier.PRIVATE), context.getType(boolean.class), CONTAINS_FALLBACK); var.addAnnotationMirror(new CodeAnnotationMirror(context.getTruffleTypes().getCompilationFinal())); clazz.add(var); } clazz.add(createExecuteUninitialized()); } if (!specialization.isUninitialized() && specialization.getNode().needsRewrites(context)) { clazz.add(createCopyConstructorFactoryMethod(nodeGen.asType(), specialization)); } else { for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) { if (constructor.getParameters().size() == 1 && ((CodeVariableElement) constructor.getParameters().get(0)).getType().equals(nodeGen.asType())) { // skip copy constructor - not used continue; } clazz.add(createConstructorFactoryMethod(specialization, constructor)); } } } protected void createConstructors(CodeTypeElement clazz) { TypeElement superTypeElement = ElementUtils.fromTypeMirror(clazz.getSuperclass()); SpecializationData specialization = getModel(); NodeData node = specialization.getNode(); for (ExecutableElement constructor : ElementFilter.constructorsIn(superTypeElement.getEnclosedElements())) { if (specialization.isUninitialized()) { // ignore copy constructors for uninitialized if not polymorphic if (isCopyConstructor(constructor) && !node.isPolymorphic(context)) { continue; } } else if (node.getUninitializedSpecialization() != null) { // ignore others than copy constructors for specialized nodes if (!isCopyConstructor(constructor)) { continue; } } CodeExecutableElement superConstructor = createSuperConstructor(clazz, constructor); if (superConstructor == null) { continue; } CodeTree body = superConstructor.getBodyTree(); CodeTreeBuilder builder = superConstructor.createBuilder(); builder.tree(body); if (superConstructor != null) { for (Parameter param : getImplicitTypeParameters(getModel())) { clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), getContext().getType(Class.class), implicitTypeName(param))); superConstructor.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param))); builder.startStatement(); builder.string("this.").string(implicitTypeName(param)).string(" = ").string(implicitTypeName(param)); builder.end(); } clazz.add(superConstructor); } } } protected void createExecuteMethods(SpecializationData specialization) { NodeData node = specialization.getNode(); CodeTypeElement clazz = getElement(); List primaryExecutes = null; int lastEvaluatedCount = -1; for (ExecutableTypeData execType : node.getExecutableTypes()) { if (execType.isFinal()) { continue; } if (execType.getEvaluatedCount() != lastEvaluatedCount) { lastEvaluatedCount = execType.getEvaluatedCount(); primaryExecutes = findFunctionalExecutableType(specialization, lastEvaluatedCount); } CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true); clazz.add(executeMethod); CodeTreeBuilder builder = executeMethod.getBuilder(); CodeTree result = createExecuteBody(builder, specialization, execType, primaryExecutes); if (result != null) { builder.tree(result); } else { clazz.remove(executeMethod); } } } protected void createCachedExecuteMethods(SpecializationData specialization) { NodeData node = specialization.getNode(); if (!node.isPolymorphic(context)) { return; } CodeTypeElement clazz = getElement(); final SpecializationData polymorphic = node.getPolymorphicSpecialization(); ExecutableElement executeCached = nodeGen.getMethod(EXECUTE_CHAINED); CodeExecutableElement executeMethod = CodeExecutableElement.clone(getContext().getEnvironment(), executeCached); executeMethod.getModifiers().remove(Modifier.ABSTRACT); CodeTreeBuilder builder = executeMethod.createBuilder(); if (specialization.isPolymorphic()) { builder.startReturn().startCall("this.next0", EXECUTE_CHAINED); addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, false, null); builder.end().end(); } else if (specialization.isUninitialized()) { builder.tree(createDeoptimizeUninitialized(node, builder)); builder.startReturn().startCall("this", EXECUTE_UNINITIALIZED); addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, false, null); builder.end().end(); } else { CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); elseBuilder.startReturn().startCall("this.next0", EXECUTE_CHAINED); addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, false, null); elseBuilder.end().end(); builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), new CodeBlock() { public CodeTree create(CodeTreeBuilder b, SpecializationData current) { return createGenericInvoke(b, polymorphic, current); } }, elseBuilder.getRoot(), false, true, true, false)); } clazz.add(executeMethod); } private CodeTree createDeoptimizeUninitialized(NodeData node, CodeTreeBuilder parent) { CodeTreeBuilder builder = parent.create(); if (node.getGenericSpecialization().isReachable()) { builder.startIf().string("!containsFallback").end().startBlock(); builder.tree(createDeoptimize(builder)); builder.end(); } else { builder.tree(createDeoptimize(builder)); } return builder.getRoot(); } private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType, List primaryExecutes) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) { builder.tree(createFunctionalExecute(builder, specialization, execType)); } else if (needsCastingExecuteMethod(execType)) { assert !primaryExecutes.isEmpty(); builder.tree(createCastingExecute(builder, specialization, execType, primaryExecutes.get(0))); } else { return null; } return builder.getRoot(); } private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) { CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod()); method.getAnnotationMirrors().clear(); for (VariableElement variable : method.getParameters()) { variable.getAnnotationMirrors().clear(); } CodeTreeBuilder builder = method.createBuilder(); int i = 0; int signatureIndex = -1; for (VariableElement param : method.getParameters()) { CodeVariableElement var = CodeVariableElement.clone(param); Parameter actualParameter = i < execType.getParameters().size() ? execType.getParameters().get(i) : null; String name; if (actualParameter != null) { if (actualParameter.getSpecification().isSignature()) { signatureIndex++; } if (evaluated && actualParameter.getSpecification().isSignature()) { name = valueNameEvaluated(actualParameter); } else { name = valueName(actualParameter); } int varArgCount = getModel().getSignatureSize() - signatureIndex; if (evaluated && actualParameter.isTypeVarArgs()) { Parameter baseVarArgs = actualParameter; name = valueName(baseVarArgs) + "Args"; builder.startAssert().string(name).string(" != null").end(); builder.startAssert().string(name).string(".length == ").string(String.valueOf(varArgCount)).end(); if (varArgCount > 0) { List varArgsParameter = execType.getParameters().subList(i, execType.getParameters().size()); for (Parameter varArg : varArgsParameter) { if (varArgCount <= 0) { break; } TypeMirror type = baseVarArgs.getType(); if (type.getKind() == TypeKind.ARRAY) { type = ((ArrayType) type).getComponentType(); } builder.declaration(type, valueNameEvaluated(varArg), name + "[" + varArg.getTypeVarArgsIndex() + "]"); varArgCount--; } } } } else { name = "arg" + i; } var.setName(name); method.getParameters().set(i, var); i++; } method.getAnnotationMirrors().clear(); method.getModifiers().remove(Modifier.ABSTRACT); return method; } private boolean needsCastingExecuteMethod(ExecutableTypeData execType) { if (execType.isAbstract()) { return true; } if (execType.getType().isGeneric()) { return true; } return false; } private List findFunctionalExecutableType(SpecializationData specialization, int evaluatedCount) { TypeData primaryType = specialization.getReturnType().getTypeSystemType(); List otherTypes = specialization.getNode().getExecutableTypes(evaluatedCount); List filteredTypes = new ArrayList<>(); for (ExecutableTypeData compareType : otherTypes) { if (ElementUtils.typeEquals(compareType.getType().getPrimitiveType(), primaryType.getPrimitiveType())) { filteredTypes.add(compareType); } } // no direct matches found use generic where the type is Object if (filteredTypes.isEmpty()) { for (ExecutableTypeData compareType : otherTypes) { if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(getContext())) { filteredTypes.add(compareType); } } } if (filteredTypes.isEmpty()) { for (ExecutableTypeData compareType : otherTypes) { if (compareType.getType().isGeneric()) { filteredTypes.add(compareType); } } } return filteredTypes; } private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final SpecializationData specialization, final ExecutableTypeData executable) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (specialization.isUninitialized()) { builder.tree(createDeoptimizeUninitialized(specialization.getNode(), builder)); } builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null)); CodeTree returnSpecialized = null; if (specialization.findNextSpecialization() != null) { CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder); returnBuilder.tree(createDeoptimize(builder)); returnBuilder.tree(createCallRewriteMonomorphic(builder, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "One of guards " + specialization.getGuards() + " failed")); returnSpecialized = returnBuilder.getRoot(); } builder.tree(createExecuteTree(builder, specialization, SpecializationGroup.create(specialization), new CodeBlock() { public CodeTree create(CodeTreeBuilder b, SpecializationData current) { return createExecute(b, executable, specialization); } }, returnSpecialized, false, false, false, false)); return builder.getRoot(); } private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) { NodeData node = specialization.getNode(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (!specialization.getExceptions().isEmpty() || !specialization.getAssumptions().isEmpty()) { builder.startTryBlock(); } for (String assumption : specialization.getAssumptions()) { builder.startStatement(); builder.string("this.").string(assumption).string(".check()"); builder.end(); } CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent); if (specialization.isPolymorphic()) { returnBuilder.startCall("next0", EXECUTE_CHAINED); addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null); returnBuilder.end(); } else if (specialization.isUninitialized()) { returnBuilder.startCall(EXECUTE_UNINITIALIZED); addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null); returnBuilder.end(); } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { emitEncounteredSynthetic(builder, specialization); } else { returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null)); } if (!returnBuilder.isEmpty()) { TypeData targetType = node.getTypeSystem().findTypeData(builder.findMethod().getReturnType()); TypeData sourceType = specialization.getReturnType().getTypeSystemType(); builder.startReturn(); if (targetType == null || sourceType == null) { builder.tree(returnBuilder.getRoot()); } else if (sourceType.needsCastTo(targetType)) { String castMethodName = TypeSystemCodeGenerator.expectTypeMethodName(targetType); if (!executable.hasUnexpectedValue(context)) { castMethodName = TypeSystemCodeGenerator.asTypeMethodName(targetType); } builder.tree(createCallTypeSystemMethod(parent, node, castMethodName, returnBuilder.getRoot())); } else { builder.tree(returnBuilder.getRoot()); } builder.end(); } if (!specialization.getExceptions().isEmpty()) { for (SpecializationThrowsData exception : specialization.getExceptions()) { builder.end().startCatchBlock(exception.getJavaClass(), "ex"); builder.tree(createDeoptimize(builder)); builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass()))); } builder.end(); } if (!specialization.getAssumptions().isEmpty()) { builder.end().startCatchBlock(getContext().getTruffleTypes().getInvalidAssumption(), "ex"); builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "Assumption failed")); builder.end(); } return builder.getRoot(); } protected CodeExecutableElement createCopyConstructorFactoryMethod(TypeMirror baseType, SpecializationData specialization) { List implicitTypeParams = getImplicitTypeParameters(specialization); String baseName = "current"; CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), FACTORY_METHOD_NAME); method.addParameter(new CodeVariableElement(specialization.getNode().getNodeType(), baseName)); for (Parameter implicitTypeParam : implicitTypeParams) { method.addParameter(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(implicitTypeParam))); } CodeTreeBuilder builder = method.createBuilder(); builder.startReturn(); builder.startNew(getElement().asType()); builder.startGroup().cast(baseType, CodeTreeBuilder.singleString(baseName)).end(); for (Parameter param : implicitTypeParams) { builder.string(implicitTypeName(param)); } builder.end().end(); return method; } protected CodeExecutableElement createConstructorFactoryMethod(SpecializationData specialization, ExecutableElement constructor) { List parameters = constructor.getParameters(); CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), FACTORY_METHOD_NAME, parameters.toArray(new CodeVariableElement[parameters.size()])); CodeTreeBuilder builder = method.createBuilder(); builder.startReturn(); builder.startNew(getElement().asType()); for (VariableElement param : parameters) { builder.string(((CodeVariableElement) param).getName()); } builder.end().end(); return method; } } private interface CodeBlock { CodeTree create(CodeTreeBuilder parent, T value); } } ././@LongLink0000644000000000000000000000015600000000000011605 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/AbstractCompilationUnitFactory.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/AbstractCompilationUnitFac0000644000000000000000000000312412445312576031101 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.generator; import com.oracle.truffle.dsl.processor.java.model.*; public abstract class AbstractCompilationUnitFactory extends AbstractCodeElementFactory { @Override public final CodeCompilationUnit create(M m) { return new CodeCompilationUnit(); } @SuppressWarnings("rawtypes") @Override public CodeCompilationUnit process(CodeElement parent, M m) { return (CodeCompilationUnit) super.process(parent, m); } @Override protected abstract void createChildren(M m); } ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootroottruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/AbstractClassElementFactory.javatruffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/generator/AbstractClassElementFactor0000644000000000000000000001326712445312576031100 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.generator; import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; import static javax.lang.model.element.Modifier.*; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.model.*; public abstract class AbstractClassElementFactory extends AbstractCodeElementFactory { @Override protected abstract CodeTypeElement create(M m); @Override public CodeTypeElement getElement() { return (CodeTypeElement) super.getElement(); } protected CodeExecutableElement createConstructorUsingFields(Set modifiers, CodeTypeElement clazz) { CodeExecutableElement method = new CodeExecutableElement(modifiers, null, clazz.getSimpleName().toString()); CodeTreeBuilder builder = method.createBuilder(); TypeElement superClass = fromTypeMirror(clazz.getSuperclass()); ExecutableElement constructor = findConstructor(superClass); if (constructor != null && constructor.getParameters().size() > 0) { builder.startStatement(); builder.startSuperCall(); for (VariableElement parameter : constructor.getParameters()) { method.addParameter(new CodeVariableElement(parameter.asType(), parameter.getSimpleName().toString())); builder.string(parameter.getSimpleName().toString()); } builder.end(); // super builder.end(); // statement } for (VariableElement field : clazz.getFields()) { if (field.getModifiers().contains(STATIC)) { continue; } String fieldName = field.getSimpleName().toString(); method.addParameter(new CodeVariableElement(field.asType(), fieldName)); builder.startStatement(); builder.string("this."); builder.string(fieldName); builder.string(" = "); if (isAssignable(field.asType(), getContext().getTruffleTypes().getNode())) { builder.string("adoptChild(").string(fieldName).string(")"); } else { builder.string(fieldName); } builder.end(); // statement } return method; } private static ExecutableElement findConstructor(TypeElement clazz) { List constructors = ElementFilter.constructorsIn(clazz.getEnclosedElements()); if (constructors.isEmpty()) { return null; } else { return constructors.get(0); } } protected CodeExecutableElement createSuperConstructor(TypeElement type, ExecutableElement element) { if (element.getModifiers().contains(Modifier.PRIVATE)) { return null; } CodeExecutableElement executable = CodeExecutableElement.clone(getContext().getEnvironment(), element); executable.setReturnType(null); executable.setSimpleName(CodeNames.of(type.getSimpleName().toString())); CodeTreeBuilder b = executable.createBuilder(); b.startStatement(); b.startSuperCall(); for (VariableElement v : element.getParameters()) { b.string(v.getSimpleName().toString()); } b.end(); b.end(); return executable; } protected CodeTypeElement createClass(Template model, Set modifiers, String simpleName, TypeMirror superType, boolean enumType) { TypeElement templateType = model.getTemplateType(); PackageElement pack = getContext().getEnvironment().getElementUtils().getPackageOf(templateType); CodeTypeElement clazz = new CodeTypeElement(modifiers, enumType ? ElementKind.ENUM : ElementKind.CLASS, pack, simpleName); TypeMirror resolvedSuperType = superType; if (resolvedSuperType == null) { resolvedSuperType = getContext().getType(Object.class); } clazz.setSuperClass(resolvedSuperType); CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) getContext().getType(GeneratedBy.class)); generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(templateType.asType())); if (model.getTemplateMethodName() != null) { generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("methodName"), new CodeAnnotationValue(model.getTemplateMethodName())); } clazz.addAnnotationMirror(generatedByAnnotation); return clazz; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/CompileErrorException.java0000644000000000000000000000241712445312576027104 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor; public class CompileErrorException extends RuntimeException { private static final long serialVersionUID = 1L; public CompileErrorException(String message) { super(message); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/0000755000000000000000000000000012460760144023047 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/ParameterSpec.java0000644000000000000000000001003012445312576026444 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.MethodSpec.TypeDef; public class ParameterSpec { private final String name; private final List allowedTypes; private final Set allowedTypesIdentifier; /** Type is bound to local final variable. */ private boolean local; private boolean signature; /** Optional bound execution of node. */ private NodeExecutionData execution; private TypeDef typeDefinition; public ParameterSpec(String name, List allowedTypes, Set typeIdentifiers) { this.name = name; this.allowedTypes = allowedTypes; this.allowedTypesIdentifier = typeIdentifiers; } public ParameterSpec(String name, TypeMirror type) { this(name, Arrays.asList(type), new HashSet<>(Arrays.asList(ElementUtils.getUniqueIdentifier(type)))); } public ParameterSpec(ParameterSpec o, List allowedTypes, Set typeIdentifiers) { this.name = o.name; this.local = o.local; this.typeDefinition = o.typeDefinition; this.execution = o.execution; this.signature = o.signature; this.allowedTypes = allowedTypes; this.allowedTypesIdentifier = typeIdentifiers; } public NodeExecutionData getExecution() { return execution; } public void setExecution(NodeExecutionData executionData) { this.execution = executionData; this.signature = execution != null; } public void setSignature(boolean signature) { this.signature = signature; } void setTypeDefinition(TypeDef typeDefinition) { this.typeDefinition = typeDefinition; } TypeDef getTypeDefinition() { return typeDefinition; } public void setLocal(boolean local) { this.local = local; } public boolean isSignature() { return signature; } public boolean isLocal() { return local; } public String getName() { return name; } public List getAllowedTypes() { return allowedTypes; } public boolean matches(TypeMirror actualType) { return allowedTypesIdentifier.contains(ElementUtils.getUniqueIdentifier(actualType)); } @Override public String toString() { return toSignatureString(false); } public String toSignatureString(boolean typeOnly) { StringBuilder builder = new StringBuilder(); if (typeDefinition != null) { builder.append("<" + typeDefinition.getName() + ">"); } else if (getAllowedTypes().size() >= 1) { builder.append(ElementUtils.getSimpleName(getAllowedTypes().get(0))); } else { builder.append("void"); } if (!typeOnly) { builder.append(" "); builder.append(getName()); } return builder.toString(); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/NodeData.java0000644000000000000000000003723312445312576025406 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; public class NodeData extends Template implements Comparable { private final String nodeId; private final String shortName; private final List enclosingNodes = new ArrayList<>(); private NodeData declaringNode; private final TypeSystemData typeSystem; private final List children; private final List childExecutions; private final List fields; private final List assumptions; private ParameterSpec instanceParameterSpec; private final List specializations = new ArrayList<>(); private final List shortCircuits = new ArrayList<>(); private final List casts = new ArrayList<>(); private Map> executableTypes; private final NodeExecutionData thisExecution; public NodeData(ProcessorContext context, TypeElement type, String shortName, TypeSystemData typeSystem, List children, List executions, List fields, List assumptions) { super(context, type, null, null); this.nodeId = type.getSimpleName().toString(); this.shortName = shortName; this.typeSystem = typeSystem; this.fields = fields; this.children = children; this.childExecutions = executions; this.assumptions = assumptions; this.thisExecution = new NodeExecutionData(new NodeChildData(null, null, "this", getNodeType(), getNodeType(), null, Cardinality.ONE), -1, false); this.thisExecution.getChild().setNode(this); } public NodeData(ProcessorContext context, TypeElement type) { this(context, type, null, null, null, null, null, null); } public NodeExecutionData getThisExecution() { return thisExecution; } public boolean isFallbackReachable() { SpecializationData generic = getGenericSpecialization(); if (generic != null) { return generic.isReachable(); } return false; } public void addEnclosedNode(NodeData node) { this.enclosingNodes.add(node); node.declaringNode = this; } public List getChildExecutions() { return childExecutions; } public int getSignatureSize() { if (getSpecializations() != null && !getSpecializations().isEmpty()) { return getSpecializations().get(0).getSignatureSize(); } return 0; } public boolean isFrameUsedByAnyGuard(ProcessorContext context) { for (SpecializationData specialization : specializations) { if (!specialization.isReachable()) { continue; } if (specialization.isFrameUsedByGuard(context)) { return true; } } return false; } public boolean isPolymorphic(ProcessorContext context) { return needsRewrites(context); } public List getCasts() { return casts; } public String getShortName() { return shortName; } public List getFields() { return fields; } @Override protected List findChildContainers() { List containerChildren = new ArrayList<>(); if (enclosingNodes != null) { containerChildren.addAll(enclosingNodes); } if (typeSystem != null) { containerChildren.add(typeSystem); } if (specializations != null) { for (MessageContainer specialization : specializations) { if (specialization.getMessageElement() != null) { containerChildren.add(specialization); } } } if (executableTypes != null) { containerChildren.addAll(getExecutableTypes()); } if (shortCircuits != null) { containerChildren.addAll(shortCircuits); } if (children != null) { containerChildren.addAll(children); } if (fields != null) { containerChildren.addAll(fields); } if (casts != null) { containerChildren.addAll(casts); } return containerChildren; } public ParameterSpec getInstanceParameterSpec() { return instanceParameterSpec; } public void setInstanceParameterSpec(ParameterSpec instanceParameter) { this.instanceParameterSpec = instanceParameter; } public String getNodeId() { return nodeId; } public TypeMirror getNodeType() { return getTemplateType().asType(); } public List getAssumptions() { return assumptions; } public boolean needsFactory() { if (specializations == null) { return false; } if (getTemplateType().getModifiers().contains(Modifier.PRIVATE)) { return false; } boolean noSpecialization = true; for (SpecializationData specialization : specializations) { noSpecialization = noSpecialization && !specialization.isSpecialized(); } return !noSpecialization; } public boolean supportsFrame() { if (executableTypes != null) { for (ExecutableTypeData execType : getExecutableTypes(-1)) { if (execType.findParameter("frameValue") == null) { return false; } } } return true; } public NodeExecutionData findExecutionByExpression(String childNameExpression) { String childName = childNameExpression; int index = -1; int start = childName.indexOf('['); int end = childName.lastIndexOf(']'); if (start != -1 && end != -1 && start < end) { try { index = Integer.parseInt(childName.substring(start + 1, end)); childName = childName.substring(0, start); childName = NodeExecutionData.createName(childName, index); } catch (NumberFormatException e) { // ignore } } for (NodeExecutionData execution : childExecutions) { if (execution.getName().equals(childName) && (execution.getIndex() == -1 || execution.getIndex() == index)) { return execution; } } return null; } public List getNodeDeclaringChildren() { List nodeChildren = new ArrayList<>(); for (NodeData child : getEnclosingNodes()) { if (child.needsFactory()) { nodeChildren.add(child); } nodeChildren.addAll(child.getNodeDeclaringChildren()); } return nodeChildren; } public NodeData getDeclaringNode() { return declaringNode; } public List getEnclosingNodes() { return enclosingNodes; } public List getAllTemplateMethods() { List methods = new ArrayList<>(); for (SpecializationData specialization : getSpecializations()) { methods.add(specialization); } methods.addAll(getExecutableTypes()); methods.addAll(getShortCircuits()); if (getCasts() != null) { methods.addAll(getCasts()); } return methods; } public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context, int evaluatedCount) { List types = findGenericExecutableTypes(context, evaluatedCount); for (ExecutableTypeData type : types) { if (type.getType().isGeneric()) { return type; } } for (ExecutableTypeData type : types) { if (!type.getType().isVoid()) { return type; } } for (ExecutableTypeData type : types) { return type; } return null; } public List getExecutableTypes(int evaluatedCount) { if (executableTypes == null) { return Collections.emptyList(); } if (evaluatedCount == -1) { List typeData = new ArrayList<>(); for (int currentEvaluationCount : executableTypes.keySet()) { typeData.addAll(executableTypes.get(currentEvaluationCount)); } return typeData; } else { List types = executableTypes.get(evaluatedCount); if (types == null) { return Collections.emptyList(); } return types; } } public List findGenericExecutableTypes(ProcessorContext context, int evaluatedCount) { List types = new ArrayList<>(); for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) { if (!type.hasUnexpectedValue(context)) { types.add(type); } } return types; } public ExecutableTypeData findExecutableType(TypeData prmitiveType, int evaluatedCount) { for (ExecutableTypeData type : getExecutableTypes(evaluatedCount)) { if (ElementUtils.typeEquals(type.getType().getPrimitiveType(), prmitiveType.getPrimitiveType())) { return type; } } return null; } public boolean needsRewrites(ProcessorContext context) { boolean needsRewrites = false; for (SpecializationData specialization : getSpecializations()) { if (specialization.hasRewrite(context)) { needsRewrites = true; break; } } return needsRewrites || getSpecializations().size() > 1; } public SpecializationData getPolymorphicSpecialization() { for (SpecializationData specialization : specializations) { if (specialization.isPolymorphic()) { return specialization; } } return null; } public SpecializationData getGenericSpecialization() { for (SpecializationData specialization : specializations) { if (specialization.isGeneric()) { return specialization; } } return null; } public SpecializationData getUninitializedSpecialization() { for (SpecializationData specialization : specializations) { if (specialization.isUninitialized()) { return specialization; } } return null; } @Override public TypeSystemData getTypeSystem() { return typeSystem; } public String dump() { return dump(0); } private String dump(int level) { String indent = ""; for (int i = 0; i < level; i++) { indent += " "; } StringBuilder builder = new StringBuilder(); builder.append(String.format("%s%s {", indent, toString())); dumpProperty(builder, indent, "templateClass", ElementUtils.getQualifiedName(getTemplateType())); dumpProperty(builder, indent, "typeSystem", getTypeSystem()); dumpProperty(builder, indent, "fields", getChildren()); dumpProperty(builder, indent, "executableTypes", getExecutableTypes()); dumpProperty(builder, indent, "specializations", getSpecializations()); dumpProperty(builder, indent, "assumptions", getAssumptions()); dumpProperty(builder, indent, "casts", getCasts()); dumpProperty(builder, indent, "messages", collectMessages()); if (getEnclosingNodes().size() > 0) { builder.append(String.format("\n%s children = [", indent)); for (NodeData node : getEnclosingNodes()) { builder.append("\n"); builder.append(node.dump(level + 1)); } builder.append(String.format("\n%s ]", indent)); } builder.append(String.format("%s}", indent)); return builder.toString(); } private static void dumpProperty(StringBuilder b, String indent, String propertyName, Object value) { if (value instanceof List) { List list = (List) value; if (!list.isEmpty()) { b.append(String.format("\n%s %s = %s", indent, propertyName, dumpList(indent, (List) value))); } } else { if (value != null) { b.append(String.format("\n%s %s = %s", indent, propertyName, value)); } } } private static String dumpList(String indent, List array) { if (array == null) { return "null"; } if (array.isEmpty()) { return "[]"; } else if (array.size() == 1) { return "[" + array.get(0).toString() + "]"; } StringBuilder b = new StringBuilder(); b.append("["); for (Object object : array) { b.append("\n "); b.append(indent); b.append(object); b.append(", "); } b.append("\n ").append(indent).append("]"); return b.toString(); } public NodeChildData findChild(String name) { for (NodeChildData field : getChildren()) { if (field.getName().equals(name)) { return field; } } return null; } public List getChildren() { return children; } public List getSpecializations() { return specializations; } public List getExecutableTypes() { return getExecutableTypes(-1); } public List getShortCircuits() { return shortCircuits; } public void setExecutableTypes(Map> executableTypes) { this.executableTypes = executableTypes; } @Override public String toString() { return getClass().getSimpleName() + "[" + getNodeId() + "]"; } public CreateCastData findCast(String name) { if (getCasts() != null) { for (CreateCastData cast : getCasts()) { if (cast.getChildNames().contains(name)) { return cast; } } } return null; } public int compareTo(NodeData o) { return getNodeId().compareTo(o.getNodeId()); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/TypeCheckData.java0000644000000000000000000000317412445312576026375 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; public class TypeCheckData extends TemplateMethod { private final TypeData checkedType; private final TypeData valueType; public TypeCheckData(TemplateMethod method, TypeData checkedType, TypeData valueType) { super(method); this.checkedType = checkedType; this.valueType = valueType; } public boolean isGeneric() { return valueType.isGeneric(); } public TypeData getCheckedType() { return checkedType; } public TypeData getValueType() { return valueType; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/NodeChildData.java0000644000000000000000000001031412445312576026341 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; public class NodeChildData extends MessageContainer { public enum Cardinality { ONE, MANY; public boolean isMany() { return this == MANY; } public boolean isOne() { return this == ONE; } } private final Element sourceElement; private final AnnotationMirror sourceAnnotationMirror; private final String name; private final TypeMirror type; private final TypeMirror originalType; private final Element accessElement; private final Cardinality cardinality; private List executeWith = Collections.emptyList(); private NodeData childNode; public NodeChildData(Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement, Cardinality cardinality) { this.sourceElement = sourceElement; this.sourceAnnotationMirror = sourceMirror; this.name = name; this.type = nodeType; this.originalType = originalNodeType; this.accessElement = accessElement; this.cardinality = cardinality; } public List getExecuteWith() { return executeWith; } public void setExecuteWith(List executeWith) { this.executeWith = executeWith; } public ExecutableTypeData findExecutableType(ProcessorContext context, TypeData targetType) { ExecutableTypeData executableType = childNode.findExecutableType(targetType, getExecuteWith().size()); if (executableType == null) { executableType = findAnyGenericExecutableType(context); } return executableType; } public List findGenericExecutableTypes(ProcessorContext context) { return childNode.findGenericExecutableTypes(context, getExecuteWith().size()); } public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context) { return childNode.findAnyGenericExecutableType(context, getExecuteWith().size()); } public TypeMirror getOriginalType() { return originalType; } @Override public Element getMessageElement() { return sourceElement; } @Override public AnnotationMirror getMessageAnnotation() { return sourceAnnotationMirror; } public void setNode(NodeData nodeData) { this.childNode = nodeData; if (nodeData != null) { getMessages().addAll(nodeData.collectMessages()); } } public Element getAccessElement() { return accessElement; } public TypeMirror getNodeType() { return type; } public Cardinality getCardinality() { return cardinality; } public NodeData getNodeData() { return childNode; } public String getName() { return name; } @Override public String toString() { return "NodeFieldData[name=" + getName() + ", kind=" + cardinality + ", node=" + getNodeData() + "]"; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/NodeExecutionData.java0000644000000000000000000000560112445312576027264 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.model.NodeChildData.Cardinality; public class NodeExecutionData { private final NodeChildData child; private final String name; private final int index; private final boolean shortCircuit; public NodeExecutionData(NodeChildData child, int index, boolean shortCircuit) { this.child = child; this.index = index; this.shortCircuit = shortCircuit; this.name = createName(); } private String createName() { return createName(child.getName(), index); } public TypeMirror getNodeType() { TypeMirror type; if (child.getCardinality() == Cardinality.MANY && child.getNodeType().getKind() == TypeKind.ARRAY) { type = ((ArrayType) child.getNodeType()).getComponentType(); } else { type = child.getNodeType(); } return type; } public String getName() { return name; } public NodeChildData getChild() { return child; } public int getIndex() { return index; } public boolean isIndexed() { return index > -1; } public boolean isShortCircuit() { return shortCircuit; } public String getShortCircuitId() { return createShortCircuitId(child, index); } public static String createShortCircuitId(NodeChildData child, int varArgsIndex) { String shortCircuitName = child.getName(); if (child.getCardinality().isMany()) { shortCircuitName = shortCircuitName + "[" + varArgsIndex + "]"; } return shortCircuitName; } public static String createName(String childName, int index) { if (index > -1) { return childName + index; } return childName; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/NodeFieldData.java0000644000000000000000000000445112445312576026346 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import javax.lang.model.element.*; import javax.lang.model.type.*; public class NodeFieldData extends MessageContainer { private final Element messageElement; private final AnnotationMirror messageAnnotation; private final String name; private final TypeMirror type; private final boolean generated; private ExecutableElement getter; public NodeFieldData(Element messageElement, AnnotationMirror messageAnnotation, TypeMirror type, String name, boolean generated) { this.messageElement = messageElement; this.messageAnnotation = messageAnnotation; this.name = name; this.type = type; this.generated = generated; } public void setGetter(ExecutableElement getter) { this.getter = getter; } @Override public Element getMessageElement() { return messageElement; } @Override public AnnotationMirror getMessageAnnotation() { return messageAnnotation; } public String getName() { return name; } public TypeMirror getType() { return type; } public boolean isGenerated() { return generated; } public ExecutableElement getGetter() { return getter; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/SpecializationThrowsData.java0000644000000000000000000000470012445312576030677 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import javax.lang.model.element.*; import javax.lang.model.type.*; public class SpecializationThrowsData extends MessageContainer { private final AnnotationValue annotationValue; private final AnnotationMirror annotationMirror; private final TypeMirror javaClass; private SpecializationData specialization; public SpecializationThrowsData(AnnotationMirror annotationMirror, AnnotationValue value, TypeMirror javaClass) { this.annotationMirror = annotationMirror; this.annotationValue = value; this.javaClass = javaClass; } void setSpecialization(SpecializationData specialization) { this.specialization = specialization; } @Override public Element getMessageElement() { return specialization.getMessageElement(); } @Override public AnnotationMirror getMessageAnnotation() { return annotationMirror; } @Override public AnnotationValue getMessageAnnotationValue() { return annotationValue; } public TypeMirror getJavaClass() { return javaClass; } public SpecializationData getSpecialization() { return specialization; } public AnnotationMirror getAnnotationMirror() { return annotationMirror; } public SpecializationData getTransitionTo() { return specialization.findNextSpecialization(); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/CreateCastData.java0000644000000000000000000000264712445312576026540 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; public class CreateCastData extends TemplateMethod { private final List childNames; public CreateCastData(TemplateMethod method, List childNames) { super(method); this.childNames = childNames; } public List getChildNames() { return childNames; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/TypeData.java0000644000000000000000000001163312445312576025436 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; public class TypeData extends MessageContainer implements Comparable { private final TypeSystemData typeSystem; private final AnnotationValue annotationValue; private final TypeMirror primitiveType; private final TypeMirror boxedType; private final int index; private final List typeCasts = new ArrayList<>(); private final List typeChecks = new ArrayList<>(); public TypeData(TypeSystemData typeSystem, int index, AnnotationValue value, TypeMirror primitiveType, TypeMirror boxedType) { this.index = index; this.typeSystem = typeSystem; this.annotationValue = value; this.primitiveType = primitiveType; this.boxedType = boxedType; } public int getIndex() { return index; } @Override public Element getMessageElement() { return typeSystem.getMessageElement(); } @Override public AnnotationMirror getMessageAnnotation() { return typeSystem.getMessageAnnotation(); } @Override public AnnotationValue getMessageAnnotationValue() { return annotationValue; } public void addTypeCast(TypeCastData typeCast) { this.typeCasts.add(typeCast); } public void addTypeCheck(TypeCheckData typeCheck) { this.typeChecks.add(typeCheck); } public List getTypeCasts() { return typeCasts; } public List getTypeChecks() { return typeChecks; } public TypeSystemData getTypeSystem() { return typeSystem; } public TypeMirror getPrimitiveType() { return primitiveType; } public TypeMirror getBoxedType() { return boxedType; } public boolean isGeneric() { return ElementUtils.typeEquals(boxedType, getTypeSystem().getGenericType()); } public boolean isVoid() { if (getTypeSystem().getVoidType() == null) { return false; } return ElementUtils.typeEquals(boxedType, getTypeSystem().getVoidType().getBoxedType()); } public int compareTo(TypeData o) { if (this.equals(o)) { return 0; } return index - o.index; } @Override public int hashCode() { return Objects.hash(index, primitiveType); } @Override public boolean equals(Object obj) { if (!(obj instanceof TypeData)) { return false; } TypeData otherType = (TypeData) obj; return index == otherType.index && ElementUtils.typeEquals(primitiveType, otherType.primitiveType); } @Override public String toString() { return getClass().getSimpleName() + "[" + ElementUtils.getSimpleName(primitiveType) + "]"; } public boolean equalsType(TypeData actualTypeData) { return ElementUtils.typeEquals(boxedType, actualTypeData.boxedType); } public boolean needsCastTo(TypeData targetType) { return ElementUtils.needsCastTo(getPrimitiveType(), targetType.getPrimitiveType()); } public boolean needsCastTo(TypeMirror targetType) { return ElementUtils.needsCastTo(getPrimitiveType(), targetType); } public boolean isPrimitive() { return ElementUtils.isPrimitive(getPrimitiveType()); } public boolean isImplicitSubtypeOf(TypeData other) { List casts = other.getTypeSystem().lookupByTargetType(other); for (ImplicitCastData cast : casts) { if (isSubtypeOf(cast.getSourceType())) { return true; } } return isSubtypeOf(other); } public boolean isSubtypeOf(TypeData other) { return ElementUtils.isSubtype(boxedType, other.boxedType); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/GuardExpression.java0000644000000000000000000001102112445312576027034 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; public final class GuardExpression { private GuardData resolvedGuard; private NodeExecutionData[] resolvedChildren; private final String guardName; private final boolean negated; private final String[] childNames; public GuardExpression(String expression, boolean allowArguments) { String exp = expression; if (exp.startsWith("!")) { exp = exp.substring(1, exp.length()); negated = true; } else { negated = false; } int argumentStart = exp.indexOf('('); int endIndex = exp.lastIndexOf(')'); if (allowArguments && argumentStart != -1 && endIndex != -1) { guardName = exp.substring(0, argumentStart).trim(); String arguments = exp.substring(argumentStart + 1, endIndex); String[] children = arguments.split(","); for (int i = 0; i < children.length; i++) { children[i] = children[i].trim(); } if (children.length == 1 && children[0].isEmpty()) { childNames = new String[0]; } else { childNames = children; } } else { guardName = exp; childNames = null; } } public String[] getChildNames() { return childNames; } public boolean isResolved() { return resolvedGuard != null; } public String getGuardName() { return guardName; } public NodeExecutionData[] getResolvedChildren() { return resolvedChildren; } public void setResolvedChildren(NodeExecutionData[] resolvedChildren) { this.resolvedChildren = resolvedChildren; } public void setResolvedGuard(GuardData guard) { this.resolvedGuard = guard; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } else if (obj instanceof GuardExpression) { GuardExpression other = (GuardExpression) obj; if (isResolved() && other.isResolved()) { return resolvedGuard.equals(other.resolvedGuard) && negated == other.negated && Arrays.equals(resolvedChildren, other.resolvedChildren); } else { boolean equal = guardName.equals(other.guardName) && negated == other.negated; if (childNames != null && other.childNames != null) { equal &= Arrays.equals(childNames, other.childNames); } return equal; } } return false; } @Override public int hashCode() { return Objects.hash(guardName, negated, resolvedGuard, resolvedChildren); } public boolean implies(GuardExpression other) { if (equals(other)) { return true; } if (isResolved() && other.isResolved()) { for (GuardExpression implies : getResolvedGuard().getImpliesExpressions()) { if (implies.getGuardName().equals(other.getGuardName())) { if (implies.isNegated() == other.isNegated()) { return true; } } } } return false; } @Override public String toString() { return (negated ? "!" : "") + guardName; } public boolean isNegated() { return negated; } public GuardData getResolvedGuard() { return resolvedGuard; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/GuardData.java0000644000000000000000000000345012445312576025555 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; public class GuardData extends TemplateMethod { private List impliesExpressions; public GuardData(TemplateMethod method, List impliesExpressions) { super(method); this.impliesExpressions = impliesExpressions; } public List getImpliesExpressions() { return impliesExpressions; } @Override public boolean equals(Object obj) { if (obj instanceof GuardData) { GuardData other = (GuardData) obj; return getMethod().equals(other.getMethod()); } return false; } @Override public int hashCode() { return getMethod().hashCode(); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/Parameter.java0000644000000000000000000000736712445312576025654 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; public final class Parameter { private final ParameterSpec specification; private TypeData typeSystemType; private TemplateMethod method; private final String localName; private final int specificationVarArgsIndex; private final int typeVarArgsIndex; private final TypeMirror actualType; public Parameter(ParameterSpec specification, TypeMirror actualType, int specificationVarArgsIndex, int typeVarArgsIndex) { this.specification = specification; this.actualType = actualType; this.typeSystemType = null; this.specificationVarArgsIndex = specificationVarArgsIndex; String valueName = specification.getName() + "Value"; if (specificationVarArgsIndex > -1) { valueName += specificationVarArgsIndex; } this.typeVarArgsIndex = typeVarArgsIndex; this.localName = valueName; } public Parameter(ParameterSpec specification, TypeData actualType, int specificationIndex, int varArgsIndex) { this(specification, actualType.getPrimitiveType(), specificationIndex, varArgsIndex); this.typeSystemType = actualType; } public Parameter(Parameter parameter, TypeData otherType) { this(parameter.specification, otherType, parameter.specificationVarArgsIndex, parameter.typeVarArgsIndex); } public Parameter(Parameter parameter) { this.specification = parameter.specification; this.actualType = parameter.actualType; this.typeSystemType = parameter.typeSystemType; this.specificationVarArgsIndex = parameter.specificationVarArgsIndex; this.localName = parameter.localName; this.typeVarArgsIndex = parameter.typeVarArgsIndex; } public int getTypeVarArgsIndex() { return typeVarArgsIndex; } public int getSpecificationVarArgsIndex() { return specificationVarArgsIndex; } public String getLocalName() { return localName; } void setMethod(TemplateMethod method) { this.method = method; } public ParameterSpec getSpecification() { return specification; } public TemplateMethod getMethod() { return method; } public TypeMirror getType() { return actualType; } public TypeData getTypeSystemType() { return typeSystemType; } public boolean isTypeVarArgs() { return typeVarArgsIndex >= 0; } public Parameter getPreviousParameter() { return method.getPreviousParam(this); } @Override public String toString() { return ElementUtils.getSimpleName(actualType); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/MessageContainer.java0000644000000000000000000002354012445312576027152 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.element.*; import javax.tools.Diagnostic.Kind; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; public abstract class MessageContainer implements Iterable { private final List messages = new ArrayList<>(); public final void addWarning(String text, Object... params) { getMessages().add(new Message(null, null, this, String.format(text, params), Kind.WARNING)); } public final void addWarning(AnnotationValue value, String text, Object... params) { getMessages().add(new Message(null, value, this, String.format(text, params), Kind.WARNING)); } public final void addError(String text, Object... params) { addError(null, text, params); } public final void addError(AnnotationValue value, String text, Object... params) { getMessages().add(new Message(null, value, this, String.format(text, params), Kind.ERROR)); } public final void addError(AnnotationMirror mirror, AnnotationValue value, String text, Object... params) { getMessages().add(new Message(mirror, value, this, String.format(text, params), Kind.ERROR)); } protected List findChildContainers() { return Collections.emptyList(); } public abstract Element getMessageElement(); public MessageContainer getBaseContainer() { return null; } public Iterator iterator() { return findChildContainers().iterator(); } public final void emitMessages(ProcessorContext context, Log log) { emitMessagesImpl(context, log, new HashSet(), null); } private void emitMessagesImpl(ProcessorContext context, Log log, Set visitedSinks, List verifiedMessages) { List childMessages; if (verifiedMessages == null) { childMessages = collectMessagesWithElementChildren(new HashSet(), getMessageElement()); } else { childMessages = verifiedMessages; } verifyExpectedMessages(context, log, childMessages); for (int i = getMessages().size() - 1; i >= 0; i--) { emitDefault(context, log, getMessages().get(i)); } for (MessageContainer sink : findChildContainers()) { if (visitedSinks.contains(sink)) { continue; } visitedSinks.add(sink); if (sink.getMessageElement() == this.getMessageElement()) { sink.emitMessagesImpl(context, log, visitedSinks, childMessages); } else { sink.emitMessagesImpl(context, log, visitedSinks, null); } } } private List collectMessagesWithElementChildren(Set visitedSinks, Element e) { if (visitedSinks.contains(this)) { return Collections.emptyList(); } visitedSinks.add(this); List foundMessages = new ArrayList<>(); if (ElementUtils.typeEquals(getMessageElement().asType(), e.asType())) { foundMessages.addAll(getMessages()); } for (MessageContainer sink : findChildContainers()) { foundMessages.addAll(sink.collectMessagesWithElementChildren(visitedSinks, e)); } return foundMessages; } private void verifyExpectedMessages(ProcessorContext context, Log log, List msgs) { TypeElement expectError = context.getTruffleTypes().getExpectError(); if (expectError != null) { Element element = getMessageElement(); AnnotationMirror mirror = ElementUtils.findAnnotationMirror(element.getAnnotationMirrors(), expectError); if (mirror != null) { List values = ElementUtils.getAnnotationValueList(String.class, mirror, "value"); if (values == null) { values = Collections.emptyList(); } if (values.size() != msgs.size()) { log.message(Kind.ERROR, element, mirror, ElementUtils.getAnnotationValue(mirror, "value"), String.format("Error count expected %s but was %s.", values.size(), msgs.size())); } } } } private void emitDefault(ProcessorContext context, Log log, Message message) { Kind kind = message.getKind(); Element messageElement = getMessageElement(); AnnotationMirror messageAnnotation = getMessageAnnotation(); AnnotationValue messageValue = getMessageAnnotationValue(); if (message.getAnnotationValue() != null) { messageValue = message.getAnnotationValue(); } if (message.getAnnotationMirror() != null) { messageAnnotation = message.getAnnotationMirror(); } String text = message.getText(); TypeElement expectError = context.getTruffleTypes().getExpectError(); if (expectError != null) { AnnotationMirror mirror = ElementUtils.findAnnotationMirror(messageElement.getAnnotationMirrors(), expectError); if (mirror != null) { List expectedTexts = ElementUtils.getAnnotationValueList(String.class, mirror, "value"); boolean found = false; for (String expectedText : expectedTexts) { if (expectedText.endsWith("%") && text.startsWith(expectedText.substring(0, expectedText.length() - 1))) { found = true; break; } else if (text.equals(expectedText)) { found = true; break; } } if (!found) { log.message(kind, messageElement, mirror, ElementUtils.getAnnotationValue(mirror, "value"), "Message expected one of '%s' but was '%s'.", expectedTexts, text); } else { return; } } } log.message(kind, messageElement, messageAnnotation, messageValue, text); } public AnnotationMirror getMessageAnnotation() { return null; } public AnnotationValue getMessageAnnotationValue() { return null; } public final boolean hasErrors() { return hasErrorsImpl(new HashSet()); } public final List collectMessages() { List collectedMessages = new ArrayList<>(); collectMessagesImpl(collectedMessages, new HashSet()); return collectedMessages; } private void collectMessagesImpl(List collectedMessages, Set visitedSinks) { collectedMessages.addAll(getMessages()); for (MessageContainer sink : findChildContainers()) { if (visitedSinks.contains(sink)) { return; } visitedSinks.add(sink); sink.collectMessagesImpl(collectedMessages, visitedSinks); } } private boolean hasErrorsImpl(Set visitedSinks) { for (Message msg : getMessages()) { if (msg.getKind() == Kind.ERROR) { return true; } } for (MessageContainer sink : findChildContainers()) { if (visitedSinks.contains(sink)) { return false; } visitedSinks.add(sink); if (sink.hasErrorsImpl(visitedSinks)) { return true; } } return false; } public List getMessages() { return messages; } public static final class Message { private final MessageContainer originalContainer; private final AnnotationMirror annotationMirror; private final AnnotationValue annotationValue; private final String text; private final Kind kind; public Message(AnnotationMirror annotationMirror, AnnotationValue annotationValue, MessageContainer originalContainer, String text, Kind kind) { this.annotationMirror = annotationMirror; this.annotationValue = annotationValue; this.originalContainer = originalContainer; this.text = text; this.kind = kind; } public AnnotationMirror getAnnotationMirror() { return annotationMirror; } public AnnotationValue getAnnotationValue() { return annotationValue; } public MessageContainer getOriginalContainer() { return originalContainer; } public String getText() { return text; } public Kind getKind() { return kind; } @Override public String toString() { return kind + ": " + text; } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/SpecializationData.java0000644000000000000000000002513612445312576027476 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; public final class SpecializationData extends TemplateMethod { public enum SpecializationKind { UNINITIALIZED, SPECIALIZED, POLYMORPHIC, GENERIC } private final NodeData node; private final SpecializationKind kind; private final List exceptions; private List guards = Collections.emptyList(); private List shortCircuits; private List assumptions = Collections.emptyList(); private final Set contains = new TreeSet<>(); private final Set containsNames = new TreeSet<>(); private final Set excludedBy = new TreeSet<>(); private String insertBeforeName; private SpecializationData insertBefore; private boolean reachable; private int index; public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind, List exceptions) { super(template); this.node = node; this.kind = kind; this.exceptions = exceptions; this.index = template.getNaturalOrder(); for (SpecializationThrowsData exception : exceptions) { exception.setSpecialization(this); } } public void setInsertBefore(SpecializationData insertBefore) { this.insertBefore = insertBefore; } public void setInsertBeforeName(String insertBeforeName) { this.insertBeforeName = insertBeforeName; } public SpecializationData getInsertBefore() { return insertBefore; } public String getInsertBeforeName() { return insertBeforeName; } public Set getContainsNames() { return containsNames; } public SpecializationData(NodeData node, TemplateMethod template, SpecializationKind kind) { this(node, template, kind, new ArrayList()); } public Set getContains() { return contains; } public Set getExcludedBy() { return excludedBy; } public void setReachable(boolean reachable) { this.reachable = reachable; } public boolean isReachable() { return reachable; } public boolean isPolymorphic() { return kind == SpecializationKind.POLYMORPHIC; } @Override protected List findChildContainers() { List sinks = new ArrayList<>(); if (exceptions != null) { sinks.addAll(exceptions); } if (guards != null) { for (GuardExpression guard : guards) { if (guard.isResolved()) { sinks.add(guard.getResolvedGuard()); } } } return sinks; } public boolean hasRewrite(ProcessorContext context) { if (!getExceptions().isEmpty()) { return true; } if (!getGuards().isEmpty()) { return true; } if (!getAssumptions().isEmpty()) { return true; } for (Parameter parameter : getSignatureParameters()) { ExecutableTypeData type = parameter.getSpecification().getExecution().getChild().findExecutableType(context, parameter.getTypeSystemType()); if (type.hasUnexpectedValue(context)) { return true; } if (type.getReturnType().getTypeSystemType().needsCastTo(parameter.getTypeSystemType())) { return true; } } return false; } @Override public int compareTo(TemplateMethod other) { if (this == other) { return 0; } else if (!(other instanceof SpecializationData)) { return super.compareTo(other); } SpecializationData m2 = (SpecializationData) other; int kindOrder = kind.compareTo(m2.kind); if (kindOrder != 0) { return kindOrder; } int compare = 0; int order1 = index; int order2 = m2.index; if (order1 != NO_NATURAL_ORDER && order2 != NO_NATURAL_ORDER) { compare = Integer.compare(order1, order2); if (compare != 0) { return compare; } } return super.compareTo(other); } public void setIndex(int order) { this.index = order; } public int getIndex() { return index; } public boolean isContainedBy(SpecializationData next) { if (compareTo(next) > 0) { // must be declared after the current specialization return false; } Iterator currentSignature = getSignatureParameters().iterator(); Iterator nextSignature = next.getSignatureParameters().iterator(); while (currentSignature.hasNext() && nextSignature.hasNext()) { TypeData currentType = currentSignature.next().getTypeSystemType(); TypeData prevType = nextSignature.next().getTypeSystemType(); if (!currentType.isImplicitSubtypeOf(prevType)) { return false; } } for (String nextAssumption : next.getAssumptions()) { if (!getAssumptions().contains(nextAssumption)) { return false; } } Iterator nextGuards = next.getGuards().iterator(); while (nextGuards.hasNext()) { GuardExpression nextGuard = nextGuards.next(); boolean implied = false; for (GuardExpression currentGuard : getGuards()) { if (currentGuard.implies(nextGuard)) { implied = true; break; } } if (!implied) { return false; } } return true; } public String createReferenceName() { if (getMethod() == null) { return "-"; } return ElementUtils.createReferenceName(getMethod()); } public NodeData getNode() { return node; } public void setGuards(List guards) { this.guards = guards; } public boolean isSpecialized() { return kind == SpecializationKind.SPECIALIZED; } public boolean isGeneric() { return kind == SpecializationKind.GENERIC; } public boolean isUninitialized() { return kind == SpecializationKind.UNINITIALIZED; } public List getExceptions() { return exceptions; } public List getGuards() { return guards; } public void setShortCircuits(List shortCircuits) { this.shortCircuits = shortCircuits; } public List getShortCircuits() { return shortCircuits; } public List getAssumptions() { return assumptions; } public void setAssumptions(List assumptions) { this.assumptions = assumptions; } public SpecializationData findNextSpecialization() { List specializations = node.getSpecializations(); for (int i = 0; i < specializations.size() - 1; i++) { if (specializations.get(i) == this) { return specializations.get(i + 1); } } return null; } @Override public String toString() { return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getTypeSignature()); } public boolean isFrameUsedByGuard(ProcessorContext context) { for (GuardExpression guard : getGuards()) { if (guard.getResolvedGuard() == null) { continue; } for (Parameter param : guard.getResolvedGuard().getParameters()) { if (ElementUtils.typeEquals(param.getType(), context.getTruffleTypes().getFrame())) { return true; } } } return false; } public boolean isReachableAfter(SpecializationData prev) { if (!prev.isSpecialized()) { return true; } if (!prev.getExceptions().isEmpty()) { return true; } Iterator currentSignature = getSignatureParameters().iterator(); Iterator prevSignature = prev.getSignatureParameters().iterator(); while (currentSignature.hasNext() && prevSignature.hasNext()) { TypeData currentType = currentSignature.next().getTypeSystemType(); TypeData prevType = prevSignature.next().getTypeSystemType(); if (!currentType.isImplicitSubtypeOf(prevType)) { return true; } } for (String prevAssumption : prev.getAssumptions()) { if (!getAssumptions().contains(prevAssumption)) { return true; } } Iterator prevGuards = prev.getGuards().iterator(); Iterator currentGuards = getGuards().iterator(); while (prevGuards.hasNext()) { GuardExpression prevGuard = prevGuards.next(); GuardExpression currentGuard = currentGuards.hasNext() ? currentGuards.next() : null; if (currentGuard == null || !currentGuard.implies(prevGuard)) { return true; } } return false; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/TemplateMethod.java0000644000000000000000000003467312445312576026650 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.util.*; /** * Note: this class has a natural ordering that is inconsistent with equals. */ public class TemplateMethod extends MessageContainer implements Comparable { public static final int NO_NATURAL_ORDER = -1; private String id; private final Template template; private final int naturalOrder; private final MethodSpec specification; private final ExecutableElement method; private final AnnotationMirror markerAnnotation; private Parameter returnType; private final List parameters; private final Map parameterCache = new HashMap<>(); public TemplateMethod(String id, int naturalOrder, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, Parameter returnType, List parameters) { this.template = template; this.specification = specification; this.naturalOrder = naturalOrder; this.method = method; this.markerAnnotation = markerAnnotation; this.returnType = returnType; this.parameters = new ArrayList<>(); for (Parameter param : parameters) { Parameter newParam = new Parameter(param); this.parameters.add(newParam); newParam.setMethod(this); parameterCache.put(param.getLocalName(), param); } if (returnType != null) { parameterCache.put(returnType.getLocalName(), returnType); } this.id = id; } public int getNaturalOrder() { return naturalOrder; } public TemplateMethod(TemplateMethod method) { this(method.id, method.naturalOrder, method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters); getMessages().addAll(method.getMessages()); } public TemplateMethod(TemplateMethod method, ExecutableElement executable) { this(method.id, method.naturalOrder, method.template, method.specification, executable, method.markerAnnotation, method.returnType, method.parameters); getMessages().addAll(method.getMessages()); } @Override public Element getMessageElement() { return method; } @Override public AnnotationMirror getMessageAnnotation() { return markerAnnotation; } @Override protected List findChildContainers() { return Collections.emptyList(); } public void setId(String id) { this.id = id; } public String getId() { return id; } public Template getTemplate() { return template; } public MethodSpec getSpecification() { return specification; } public Parameter getReturnType() { return returnType; } public void replaceParameter(String localName, Parameter newParameter) { if (returnType.getLocalName().equals(localName)) { returnType = newParameter; returnType.setMethod(this); } else { Parameter local = findParameter(localName); int index = parameters.indexOf(local); parameters.set(index, newParameter); } } public List getRequiredParameters() { List requiredParameters = new ArrayList<>(); for (Parameter parameter : getParameters()) { if (getSpecification().getRequired().contains(parameter.getSpecification())) { requiredParameters.add(parameter); } } return requiredParameters; } public Iterable getSignatureParameters() { return new FilteredIterable<>(getParameters(), new Predicate() { public boolean evaluate(Parameter value) { return value.getSpecification().isSignature(); } }); } public List getParameters() { return parameters; } public List findParameters(ParameterSpec spec) { List foundParameters = new ArrayList<>(); for (Parameter param : getReturnTypeAndParameters()) { if (param.getSpecification().getName().equals(spec.getName())) { foundParameters.add(param); } } return foundParameters; } public List findByExecutionData(NodeExecutionData execution) { List foundParameters = new ArrayList<>(); for (Parameter parameter : getParameters()) { ParameterSpec spec = parameter.getSpecification(); if (spec != null && spec.getExecution() != null && spec.getExecution().equals(execution) && parameter.getSpecification().isSignature()) { foundParameters.add(parameter); } } return foundParameters; } public Parameter findParameter(String valueName) { return parameterCache.get(valueName); } public List getReturnTypeAndParameters() { List allParameters = new ArrayList<>(getParameters().size() + 1); if (getReturnType() != null) { allParameters.add(getReturnType()); } allParameters.addAll(getParameters()); return Collections.unmodifiableList(allParameters); } public boolean canBeAccessedByInstanceOf(TypeMirror type) { TypeMirror methodType = ElementUtils.findNearestEnclosingType(getMethod()).asType(); return ElementUtils.isAssignable(type, methodType) || ElementUtils.isAssignable(methodType, type); } public ExecutableElement getMethod() { return method; } public String getMethodName() { if (getMethod() != null) { return getMethod().getSimpleName().toString(); } else { return "$synthetic"; } } public AnnotationMirror getMarkerAnnotation() { return markerAnnotation; } @Override public String toString() { return String.format("%s [id = %s, method = %s]", getClass().getSimpleName(), getId(), getMethod()); } public Parameter getPreviousParam(Parameter searchParam) { Parameter prev = null; for (Parameter param : getParameters()) { if (param == searchParam) { return prev; } prev = param; } return prev; } @SuppressWarnings("unused") public int getSignatureSize() { int signatureSize = 0; for (Parameter parameter : getSignatureParameters()) { signatureSize++; } return signatureSize; } public TypeSignature getTypeSignature() { TypeSignature signature = new TypeSignature(); signature.types.add(getReturnType().getTypeSystemType()); for (Parameter parameter : getSignatureParameters()) { TypeData typeData = parameter.getTypeSystemType(); if (typeData != null) { signature.types.add(typeData); } } return signature; } public Parameter getSignatureParameter(int searchIndex) { int index = 0; for (Parameter parameter : getParameters()) { if (!parameter.getSpecification().isSignature()) { continue; } if (index == searchIndex) { return parameter; } index++; } return null; } public void updateSignature(TypeSignature signature) { // TODO(CH): fails in normal usage - output ok though // assert signature.size() >= 1; int signatureIndex = 0; for (Parameter parameter : getReturnTypeAndParameters()) { if (!parameter.getSpecification().isSignature()) { continue; } if (signatureIndex >= signature.size()) { break; } TypeData newType = signature.get(signatureIndex++); if (!parameter.getTypeSystemType().equals(newType)) { replaceParameter(parameter.getLocalName(), new Parameter(parameter, newType)); } } } @Override public int compareTo(TemplateMethod o) { if (this == o) { return 0; } int compare = compareBySignature(o); if (compare == 0) { // if signature sorting failed sort by id compare = getId().compareTo(o.getId()); } if (compare == 0) { // if still no difference sort by enclosing type name TypeElement enclosingType1 = ElementUtils.findNearestEnclosingType(getMethod()); TypeElement enclosingType2 = ElementUtils.findNearestEnclosingType(o.getMethod()); compare = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString()); } return compare; } public List getParametersAfter(Parameter genericParameter) { boolean found = false; List foundParameters = new ArrayList<>(); for (Parameter param : getParameters()) { if (param.getLocalName().equals(genericParameter.getLocalName())) { found = true; } else if (found) { foundParameters.add(param); } } return foundParameters; } public int compareBySignature(TemplateMethod compareMethod) { final TypeSystemData typeSystem = getTemplate().getTypeSystem(); if (typeSystem != compareMethod.getTemplate().getTypeSystem()) { throw new IllegalStateException("Cannot compare two methods with different type systems."); } List signature1 = getSignatureTypes(this); List signature2 = getSignatureTypes(compareMethod); int result = 0; for (int i = 0; i < Math.max(signature1.size(), signature2.size()); i++) { TypeMirror t1 = i < signature1.size() ? signature1.get(i) : null; TypeMirror t2 = i < signature2.size() ? signature2.get(i) : null; result = compareParameter(typeSystem, t1, t2); if (result != 0) { break; } } return result; } protected static int compareParameter(TypeSystemData data, TypeMirror signature1, TypeMirror signature2) { if (signature1 == null) { return 1; } else if (signature2 == null) { return -1; } if (ElementUtils.typeEquals(signature1, signature2)) { return 0; } int index1 = data.findType(signature1); int index2 = data.findType(signature2); if (index1 != -1 && index2 != -1) { return index1 - index2; } // TODO this version if subclass of should be improved. if (signature1.getKind() == TypeKind.DECLARED && signature2.getKind() == TypeKind.DECLARED) { TypeElement element1 = ElementUtils.fromTypeMirror(signature1); TypeElement element2 = ElementUtils.fromTypeMirror(signature2); if (ElementUtils.getDirectSuperTypes(element1).contains(element2)) { return -1; } else if (ElementUtils.getDirectSuperTypes(element2).contains(element1)) { return 1; } } return ElementUtils.getSimpleName(signature1).compareTo(ElementUtils.getSimpleName(signature2)); } public static List getSignatureTypes(TemplateMethod method) { List types = new ArrayList<>(); for (Parameter param : method.getSignatureParameters()) { types.add(param.getType()); } return types; } public static class TypeSignature implements Iterable, Comparable { private final List types; public TypeSignature() { this.types = new ArrayList<>(); } public TypeSignature(List signature) { this.types = signature; } @Override public int hashCode() { return types.hashCode(); } public int size() { return types.size(); } public TypeData get(int index) { return types.get(index); } public int compareTo(TypeSignature other) { if (this == other) { return 0; } else if (types.size() != other.types.size()) { return types.size() - other.types.size(); } else if (types.isEmpty()) { return 0; } for (int i = 0; i < types.size(); i++) { TypeData type1 = types.get(i); TypeData type2 = other.types.get(i); int comparison = type1.compareTo(type2); if (comparison != 0) { return comparison; } } return 0; } @Override public boolean equals(Object obj) { if (obj instanceof TypeSignature) { return ((TypeSignature) obj).types.equals(types); } return super.equals(obj); } public Iterator iterator() { return types.iterator(); } @Override public String toString() { return types.toString(); } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/Template.java0000644000000000000000000000511512445312576025474 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.element.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; public abstract class Template extends MessageContainer { private final ProcessorContext context; private final TypeElement templateType; private final String templateMethodName; private final AnnotationMirror annotation; public Template(ProcessorContext context, TypeElement templateType, String templateMethodName, AnnotationMirror annotation) { this.context = context; this.templateType = templateType; this.templateMethodName = templateMethodName; this.annotation = annotation; } public ProcessorContext getContext() { return context; } @Override public MessageContainer getBaseContainer() { return this; } public abstract TypeSystemData getTypeSystem(); @Override public Element getMessageElement() { return templateType; } @Override protected List findChildContainers() { return Collections.emptyList(); } public String getTemplateMethodName() { return templateMethodName; } public TypeElement getTemplateType() { return templateType; } public AnnotationMirror getTemplateTypeAnnotation() { return annotation; } @Override public String toString() { return getClass().getSimpleName() + "[" + ElementUtils.getSimpleName(getTemplateType()) + "]"; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/TypeSystemData.java0000644000000000000000000001467412445312576026653 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; public class TypeSystemData extends Template { private List types; private List primitiveTypeMirrors = new ArrayList<>(); private List boxedTypeMirrors = new ArrayList<>(); private Map cachedTypes = new HashMap<>(); private List implicitCasts; private List casts; private List checks; private TypeMirror genericType; private TypeData voidType; public TypeSystemData(ProcessorContext context, TypeElement templateType, AnnotationMirror annotation) { super(context, templateType, null, annotation); } @Override public TypeSystemData getTypeSystem() { return this; } public void setTypes(List types) { this.types = types; if (types != null) { for (TypeData typeData : types) { primitiveTypeMirrors.add(typeData.getPrimitiveType()); boxedTypeMirrors.add(typeData.getBoxedType()); cachedTypes.put(ElementUtils.getUniqueIdentifier(typeData.getPrimitiveType()), typeData); cachedTypes.put(ElementUtils.getUniqueIdentifier(typeData.getBoxedType()), typeData); } } } public void setImplicitCasts(List implicitCasts) { this.implicitCasts = implicitCasts; } public List getImplicitCasts() { return implicitCasts; } public void setCasts(List casts) { this.casts = casts; } public void setChecks(List checks) { this.checks = checks; } public void setGenericType(TypeMirror genericType) { this.genericType = genericType; } public void setVoidType(TypeData voidType) { this.voidType = voidType; } @Override protected List findChildContainers() { List sinks = new ArrayList<>(); if (types != null) { sinks.addAll(types); } if (checks != null) { sinks.addAll(checks); } if (casts != null) { sinks.addAll(casts); } if (implicitCasts != null) { sinks.addAll(implicitCasts); } return sinks; } public TypeData getVoidType() { return voidType; } public List getBoxedTypeMirrors() { return boxedTypeMirrors; } public List getPrimitiveTypeMirrors() { return primitiveTypeMirrors; } public Set getTypeIdentifiers() { return cachedTypes.keySet(); } public List getTypes() { return types; } public TypeMirror getGenericType() { return genericType; } public TypeData getGenericTypeData() { TypeData result = types.get(types.size() - 2); assert result.getBoxedType() == genericType; return result; } public TypeData findType(String simpleName) { for (TypeData type : types) { if (ElementUtils.getTypeId(type.getBoxedType()).equals(simpleName)) { return type; } } return null; } public TypeData findTypeData(TypeMirror type) { if (ElementUtils.typeEquals(voidType.getPrimitiveType(), type)) { return voidType; } int index = findType(type); if (index == -1) { return null; } return types.get(index); } public int findType(TypeMirror type) { TypeData data = cachedTypes.get(ElementUtils.getUniqueIdentifier(type)); if (data != null) { return data.getIndex(); } return -1; } @Override public String toString() { return getClass().getSimpleName() + "[template = " + ElementUtils.getSimpleName(getTemplateType()) + ", types = " + types + "]"; } public List lookupByTargetType(TypeData targetType) { if (getImplicitCasts() == null) { return Collections.emptyList(); } List foundCasts = new ArrayList<>(); for (ImplicitCastData cast : getImplicitCasts()) { if (cast.getTargetType().equals(targetType)) { foundCasts.add(cast); } } return foundCasts; } public ImplicitCastData lookupCast(TypeData sourceType, TypeData targetType) { if (getImplicitCasts() == null) { return null; } for (ImplicitCastData cast : getImplicitCasts()) { if (cast.getSourceType().equals(sourceType) && cast.getTargetType().equals(targetType)) { return cast; } } return null; } public List lookupSourceTypes(TypeData type) { List sourceTypes = new ArrayList<>(); sourceTypes.add(type); if (getImplicitCasts() != null) { for (ImplicitCastData cast : getImplicitCasts()) { if (cast.getTargetType() == type) { sourceTypes.add(cast.getSourceType()); } } } Collections.sort(sourceTypes); return sourceTypes; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/TypeCastData.java0000644000000000000000000000317212445312576026250 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; public class TypeCastData extends TemplateMethod { private final TypeData targetType; private final TypeData sourceType; public TypeCastData(TemplateMethod method, TypeData sourceType, TypeData targetType) { super(method); this.sourceType = sourceType; this.targetType = targetType; } public boolean isGeneric() { return sourceType.isGeneric(); } public TypeData getSourceType() { return sourceType; } public TypeData getTargetType() { return targetType; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/ShortCircuitData.java0000644000000000000000000000457512445312576027146 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import com.oracle.truffle.dsl.processor.java.*; public class ShortCircuitData extends TemplateMethod { private ShortCircuitData genericShortCircuitMethod; private final String valueName; public ShortCircuitData(TemplateMethod template, String valueName) { super(template); this.valueName = valueName; } public String getValueName() { return valueName; } public void setGenericShortCircuitMethod(ShortCircuitData genericShortCircuitMethod) { this.genericShortCircuitMethod = genericShortCircuitMethod; } public boolean isGeneric() { return genericShortCircuitMethod == null; } public ShortCircuitData getGeneric() { if (isGeneric()) { return this; } else { return genericShortCircuitMethod; } } public boolean isCompatibleTo(SpecializationData specialization) { if (isGeneric() && specialization.isGeneric()) { return true; } for (Parameter param : getParameters()) { Parameter specializationParam = specialization.findParameter(param.getLocalName()); if (!ElementUtils.typeEquals(param.getType(), specializationParam.getType())) { return false; } } return true; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/ExecutableTypeData.java0000644000000000000000000000566112445312576027444 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import javax.lang.model.element.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; public class ExecutableTypeData extends TemplateMethod { private final TypeSystemData typeSystem; private final TypeData type; public ExecutableTypeData(TemplateMethod method, ExecutableElement executable, TypeSystemData typeSystem, TypeData type) { super(method, executable); this.typeSystem = typeSystem; this.type = type; if (executable.getParameters().size() < method.getMethod().getParameters().size()) { throw new IllegalArgumentException(String.format("Method parameter count mismatch %s != %s.", executable.getParameters(), method.getMethod().getParameters())); } } public TypeData getType() { return type; } public TypeSystemData getTypeSystem() { return typeSystem; } public boolean hasUnexpectedValue(ProcessorContext context) { return ElementUtils.canThrowType(getMethod().getThrownTypes(), context.getTruffleTypes().getUnexpectedValueException()); } public boolean isFinal() { return getMethod().getModifiers().contains(Modifier.FINAL); } public boolean isAbstract() { return getMethod().getModifiers().contains(Modifier.ABSTRACT); } public int getEvaluatedCount() { int count = 0; for (Parameter parameter : getParameters()) { if (parameter.getSpecification().isSignature()) { count++; } } return count; } @Override public int hashCode() { return type.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof ExecutableTypeData) { return type.equals(((ExecutableTypeData) obj).type); } return super.equals(obj); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/MethodSpec.java0000644000000000000000000001634712445312576025765 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; import java.util.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.java.*; public class MethodSpec { private final ParameterSpec returnType; private final List optional = new ArrayList<>(); private final List required = new ArrayList<>(); private boolean ignoreAdditionalParameters; private boolean ignoreAdditionalSpecifications; private boolean variableRequiredParameters; private List typeDefinitions; public MethodSpec(ParameterSpec returnType) { this.returnType = returnType; } public void setVariableRequiredParameters(boolean variableRequiredParameters) { this.variableRequiredParameters = variableRequiredParameters; } public boolean isVariableRequiredParameters() { return variableRequiredParameters; } public void setIgnoreAdditionalParameters(boolean ignoreAdditionalParameter) { this.ignoreAdditionalParameters = ignoreAdditionalParameter; } public boolean isIgnoreAdditionalParameters() { return ignoreAdditionalParameters; } public void addOptional(ParameterSpec spec) { optional.add(spec); } public ParameterSpec addRequired(ParameterSpec spec) { required.add(spec); return spec; } public ParameterSpec getReturnType() { return returnType; } public List getRequired() { return required; } public List getOptional() { return optional; } public List getAll() { List specs = new ArrayList<>(); specs.add(getReturnType()); specs.addAll(getOptional()); specs.addAll(getRequired()); return specs; } public ParameterSpec findParameterSpec(String name) { for (ParameterSpec spec : getAll()) { if (spec.getName().equals(name)) { return spec; } } return null; } public void applyTypeDefinitions(String prefix) { this.typeDefinitions = createTypeDefinitions(prefix); } private List createTypeDefinitions(String prefix) { List typeDefs = new ArrayList<>(); int defIndex = 0; for (ParameterSpec spec : getAll()) { List allowedTypes = spec.getAllowedTypes(); List types = spec.getAllowedTypes(); if (types != null && allowedTypes.size() > 1) { TypeDef foundDef = null; for (TypeDef def : typeDefs) { if (allowedTypes.equals(def.getTypes())) { foundDef = def; break; } } if (foundDef == null) { foundDef = new TypeDef(types, prefix + defIndex); typeDefs.add(foundDef); defIndex++; } spec.setTypeDefinition(foundDef); } } return typeDefs; } public String toSignatureString(String methodName) { StringBuilder b = new StringBuilder(); b.append(" "); b.append(createTypeSignature(returnType, true)); b.append(" "); b.append(methodName); b.append("("); String sep = ""; for (ParameterSpec optionalSpec : getOptional()) { b.append(sep); b.append("["); b.append(createTypeSignature(optionalSpec, false)); b.append("]"); sep = ", "; } for (int i = 0; i < getRequired().size(); i++) { ParameterSpec requiredSpec = getRequired().get(i); b.append(sep); if (isVariableRequiredParameters() && i == getRequired().size() - 1) { b.append(("{")); } b.append(createTypeSignature(requiredSpec, false)); if (isVariableRequiredParameters() && i == getRequired().size() - 1) { b.append(("}")); } sep = ", "; } b.append(")"); if (typeDefinitions != null && !typeDefinitions.isEmpty()) { b.append("\n\n"); String lineSep = ""; for (TypeDef def : typeDefinitions) { b.append(lineSep); b.append(" <").append(def.getName()).append(">"); b.append(" = {"); String separator = ""; for (TypeMirror type : def.getTypes()) { b.append(separator).append(ElementUtils.getSimpleName(type)); separator = ", "; } b.append("}"); lineSep = "\n"; } } return b.toString(); } private static String createTypeSignature(ParameterSpec spec, boolean typeOnly) { StringBuilder builder = new StringBuilder(); TypeDef foundTypeDef = spec.getTypeDefinition(); if (foundTypeDef != null) { builder.append("<" + foundTypeDef.getName() + ">"); } else if (spec.getAllowedTypes().size() >= 1) { builder.append(ElementUtils.getSimpleName(spec.getAllowedTypes().get(0))); } else { builder.append("void"); } if (!typeOnly) { builder.append(" "); builder.append(spec.getName()); } return builder.toString(); } @Override public String toString() { return toSignatureString("methodName"); } static final class TypeDef { private final List types; private final String name; private TypeDef(List types, String name) { this.types = types; this.name = name; } public List getTypes() { return types; } public String getName() { return name; } } public void setIgnoreAdditionalSpecifications(boolean ignoreAdditoinalSpecifications) { this.ignoreAdditionalSpecifications = ignoreAdditoinalSpecifications; } public boolean isIgnoreAdditionalSpecifications() { return ignoreAdditionalSpecifications; } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/model/ImplicitCastData.java0000644000000000000000000000405412445312576027101 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.model; public class ImplicitCastData extends TemplateMethod { private final TypeData sourceType; private final TypeData targetType; public ImplicitCastData(TemplateMethod method, TypeData sourceType, TypeData targetType) { super(method); this.sourceType = sourceType; this.targetType = targetType; } public TypeData getSourceType() { return sourceType; } public TypeData getTargetType() { return targetType; } @Override public int compareTo(TemplateMethod o) { if (o instanceof ImplicitCastData && sourceType != null) { // implicit casts are ordered by source type since // its also the order in which they are checked. TypeData otherSourceType = ((ImplicitCastData) o).getSourceType(); if (otherSourceType != null) { return this.sourceType.compareTo(otherSourceType); } } return super.compareTo(o); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/TruffleProcessor.java0000644000000000000000000001311112445312576026123 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor; import java.lang.annotation.*; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.*; import javax.lang.model.element.*; import javax.tools.Diagnostic.Kind; import com.oracle.truffle.dsl.processor.ProcessorContext.ProcessCallback; import com.oracle.truffle.dsl.processor.generator.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.parser.*; /** * THIS IS NOT PUBLIC API. */ // @SupportedAnnotationTypes({"com.oracle.truffle.codegen.Operation", // "com.oracle.truffle.codegen.TypeLattice"}) @SupportedSourceVersion(SourceVersion.RELEASE_7) public class TruffleProcessor extends AbstractProcessor implements ProcessCallback { private List> generators; @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { if (!roundEnv.processingOver()) { processImpl(roundEnv); } return false; } private void processImpl(RoundEnvironment env) { // TODO run verifications that other annotations are not processed out of scope of the // operation or typelattice. try { ProcessorContext.setThreadLocalInstance(new ProcessorContext(processingEnv, this)); for (AnnotationProcessor generator : getGenerators()) { AbstractParser parser = generator.getParser(); if (parser.getAnnotationType() != null) { for (Element e : env.getElementsAnnotatedWith(parser.getAnnotationType())) { processElement(generator, e, false); } } for (Class annotationType : parser.getTypeDelegatedAnnotationTypes()) { for (Element e : env.getElementsAnnotatedWith(annotationType)) { TypeElement processedType; if (parser.isDelegateToRootDeclaredType()) { processedType = ElementUtils.findRootEnclosingType(e); } else { processedType = ElementUtils.findNearestEnclosingType(e); } processElement(generator, processedType, false); } } } } finally { ProcessorContext.setThreadLocalInstance(null); } } private static void processElement(AnnotationProcessor generator, Element e, boolean callback) { try { generator.process(e, callback); } catch (Throwable e1) { handleThrowable(generator, e1, e); } } private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) { String message = "Uncaught error in " + generator.getClass().getSimpleName() + " while processing " + e; ProcessorContext.getInstance().getEnvironment().getMessager().printMessage(Kind.ERROR, message + ": " + ElementUtils.printException(t), e); } @Override public void callback(TypeElement template) { for (AnnotationProcessor generator : generators) { Class annotationType = generator.getParser().getAnnotationType(); if (annotationType != null) { Annotation annotation = template.getAnnotation(annotationType); if (annotation != null) { processElement(generator, template, true); } } } } @Override public Set getSupportedAnnotationTypes() { Set annotations = new HashSet<>(); List> annotationsTypes = new ArrayList<>(); annotationsTypes.addAll(NodeParser.ANNOTATIONS); annotationsTypes.addAll(TypeSystemParser.ANNOTATIONS); for (Class type : annotationsTypes) { annotations.add(type.getCanonicalName()); } return annotations; } private List> getGenerators() { if (generators == null && processingEnv != null) { generators = new ArrayList<>(); generators.add(new AnnotationProcessor<>(new TypeSystemParser(), new TypeSystemCodeGenerator())); generators.add(new AnnotationProcessor<>(new NodeParser(), new NodeCodeGenerator())); } return generators; } @Override public synchronized void init(ProcessingEnvironment env) { this.processingEnv = env; super.init(env); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/util/0000755000000000000000000000000012460760144022724 5ustar truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/util/FilteredIterable.java0000644000000000000000000000305012445312576027000 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.util; import java.util.*; public class FilteredIterable implements Iterable { private final Iterable delegate; private final Predicate containedPredicate; public FilteredIterable(Iterable delegate, Predicate containedPredicate) { this.delegate = delegate; this.containedPredicate = containedPredicate; } public Iterator iterator() { return new Filterator<>(delegate.iterator(), containedPredicate); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/util/Predicate.java0000644000000000000000000000222412445312576025474 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.util; public interface Predicate { boolean evaluate(T value); } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/util/Filterator.java0000644000000000000000000000471312445312576025714 0ustar /* * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor.util; import java.util.*; public class Filterator implements Iterator { private final Predicate includePredicate; private final Iterator elements; private boolean hasCached; private T cached; public Filterator(Iterator elements, Predicate includePredicate) { this.elements = elements; this.includePredicate = includePredicate; } public boolean hasNext() { if (hasCached) { return true; } nextValue(); return hasCached; } private void nextValue() { while (!hasCached && elements.hasNext()) { T element = elements.next(); if (includePredicate.evaluate(element)) { cached = element; hasCached = true; } } } public T next() { T foundCached = getCached(); if (foundCached != null) { return foundCached; } else { nextValue(); if (!hasCached) { throw new NoSuchElementException(); } return getCached(); } } private T getCached() { if (hasCached) { hasCached = false; T value = cached; cached = null; return value; } return null; } @Override public void remove() { elements.remove(); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/AnnotationProcessor.java0000644000000000000000000000734012445312576026635 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor; import java.util.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.generator.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.java.transform.*; import com.oracle.truffle.dsl.processor.model.*; import com.oracle.truffle.dsl.processor.parser.*; /** * THIS IS NOT PUBLIC API. */ class AnnotationProcessor { private final AbstractParser parser; private final AbstractCompilationUnitFactory factory; private final Set processedElements = new HashSet<>(); public AnnotationProcessor(AbstractParser parser, AbstractCompilationUnitFactory factory) { this.parser = parser; this.factory = factory; } public AbstractParser getParser() { return parser; } @SuppressWarnings({"unchecked"}) public void process(Element element, boolean callback) { // since it is not guaranteed to be called only once by the compiler // we check for already processed elements to avoid errors when writing files. if (!callback && element instanceof TypeElement) { String qualifiedName = ElementUtils.getQualifiedName((TypeElement) element); if (processedElements.contains(qualifiedName)) { return; } processedElements.add(qualifiedName); } ProcessorContext context = ProcessorContext.getInstance(); TypeElement type = (TypeElement) element; M model = (M) context.getTemplate(type.asType(), false); boolean firstRun = !context.containsTemplate(type); if (firstRun || !callback) { context.registerTemplate(type, null); model = parser.parse(element); context.registerTemplate(type, model); if (model != null) { CodeCompilationUnit unit = factory.process(null, model); unit.setGeneratorAnnotationMirror(model.getTemplateTypeAnnotation()); unit.setGeneratorElement(model.getTemplateType()); DeclaredType overrideType = (DeclaredType) context.getType(Override.class); DeclaredType unusedType = (DeclaredType) context.getType(SuppressWarnings.class); unit.accept(new GenerateOverrideVisitor(overrideType), null); unit.accept(new FixWarningsVisitor(context.getEnvironment(), unusedType, overrideType), null); if (!callback) { unit.accept(new CodeWriter(context.getEnvironment(), element), null); } } } } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/ProcessorContext.java0000644000000000000000000001061612445312576026147 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor; import java.util.*; import javax.annotation.processing.*; import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.model.*; /** * THIS IS NOT PUBLIC API. */ public class ProcessorContext { private final ProcessingEnvironment environment; private final Map models = new HashMap<>(); private final ProcessCallback callback; private final Log log; private final TruffleTypes truffleTypes; ProcessorContext(ProcessingEnvironment env, ProcessCallback callback) { this.environment = env; this.callback = callback; this.log = new Log(environment); this.truffleTypes = new TruffleTypes(this); } public TruffleTypes getTruffleTypes() { return truffleTypes; } public Log getLog() { return log; } public ProcessingEnvironment getEnvironment() { return environment; } public boolean containsTemplate(TypeElement element) { return models.containsKey(ElementUtils.getQualifiedName(element)); } public void registerTemplate(TypeElement element, Template model) { models.put(ElementUtils.getQualifiedName(element), model); } public Template getTemplate(TypeMirror templateTypeMirror, boolean invokeCallback) { String qualifiedName = ElementUtils.getQualifiedName(templateTypeMirror); Template model = models.get(qualifiedName); if (model == null && invokeCallback) { callback.callback(ElementUtils.fromTypeMirror(templateTypeMirror)); model = models.get(qualifiedName); } return model; } public TypeMirror getType(Class element) { return ElementUtils.getType(environment, element); } public interface ProcessCallback { void callback(TypeElement template); } public TypeMirror reloadTypeElement(TypeElement type) { return getType(type.getQualifiedName().toString()); } private TypeMirror getType(String className) { TypeElement element = environment.getElementUtils().getTypeElement(className); if (element != null) { return element.asType(); } return null; } public TypeMirror reloadType(TypeMirror type) { if (type instanceof CodeTypeMirror) { return type; } else if (type.getKind().isPrimitive()) { return type; } Types types = getEnvironment().getTypeUtils(); switch (type.getKind()) { case ARRAY: return types.getArrayType(reloadType(((ArrayType) type).getComponentType())); case WILDCARD: return types.getWildcardType(((WildcardType) type).getExtendsBound(), ((WildcardType) type).getSuperBound()); case DECLARED: return reloadTypeElement((TypeElement) (((DeclaredType) type).asElement())); } return type; } private static final ThreadLocal instance = new ThreadLocal<>(); public static void setThreadLocalInstance(ProcessorContext context) { instance.set(context); } public static ProcessorContext getInstance() { return instance.get(); } } truffle-dsl-processor-0.6.orig/com/oracle/truffle/dsl/processor/CodeWriter.java0000644000000000000000000000427412445312576024675 0ustar /* * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.dsl.processor; import java.io.*; import javax.annotation.processing.*; import javax.lang.model.element.*; import javax.tools.*; import com.oracle.truffle.dsl.processor.java.compiler.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.java.transform.*; public final class CodeWriter extends AbstractCodeWriter { private final Element originalElement; private final ProcessingEnvironment env; public CodeWriter(ProcessingEnvironment env, Element originalElement) { this.env = env; this.originalElement = originalElement; } @Override protected Writer createWriter(CodeTypeElement clazz) throws IOException { JavaFileObject jfo = env.getFiler().createSourceFile(clazz.getQualifiedName(), originalElement); return new BufferedWriter(jfo.openWriter()); } @Override protected void writeHeader() { if (env == null) { return; } String comment = CompilerFactory.getCompiler(originalElement).getHeaderComment(env, originalElement); if (comment != null) { writeLn(comment); } } }