From 8eb9e27bccca4a0cd6a0b1b15bee76576ce030c3 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 6 Mar 2015 07:28:35 +0100 Subject: Bug 1134 - Add ASTLocationTag, locating source of [semantic] errors while parsing / analyzing New GlueGenException supports ASTLocationTag, which will be throws in case of semantic and/or parsing errors. --- src/java/com/jogamp/gluegen/ASTLocusTag.java | 78 ++++++++++++++++++ .../com/jogamp/gluegen/ConstantDefinition.java | 15 +++- src/java/com/jogamp/gluegen/GlueGen.java | 6 +- src/java/com/jogamp/gluegen/GlueGenException.java | 95 ++++++++++++++++++++++ src/java/com/jogamp/gluegen/JavaEmitter.java | 20 +++-- src/java/com/jogamp/gluegen/cgram/TNode.java | 24 +++++- .../com/jogamp/gluegen/cgram/types/EnumType.java | 17 +++- .../jogamp/gluegen/cgram/types/FunctionSymbol.java | 15 +++- 8 files changed, 253 insertions(+), 17 deletions(-) create mode 100644 src/java/com/jogamp/gluegen/ASTLocusTag.java create mode 100644 src/java/com/jogamp/gluegen/GlueGenException.java (limited to 'src/java/com/jogamp/gluegen') diff --git a/src/java/com/jogamp/gluegen/ASTLocusTag.java b/src/java/com/jogamp/gluegen/ASTLocusTag.java new file mode 100644 index 0000000..ba38276 --- /dev/null +++ b/src/java/com/jogamp/gluegen/ASTLocusTag.java @@ -0,0 +1,78 @@ +/** + * Copyright 2015 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ +package com.jogamp.gluegen; + +/** + * An AST location tag. + */ +public class ASTLocusTag { + /** Source object, might be {@link String}. */ + public final Object source; + /** Line number, {@code -1} if undefined */ + public final int line; + /** Column number, {@code -1} if undefined */ + public final int column; + /** Source text reflecting current location, {@code null} if undefined */ + public final String text; + + public ASTLocusTag(final Object source, final int line, final int column, final String text) { + this.source = source; + this.line = line; + this.column = column; + this.text = text; + } + + public String toString() { + final StringBuffer buf = new StringBuffer(); + if (source != null) { + buf.append(source).append(": "); + } + if (line != -1) { + buf.append("line ").append(line); + if (column != -1) { + buf.append(":" + column); + } + buf.append(": "); + } + if( null != text && text.length()>0 ) { + buf.append("text '").append(text).append("'"); + } + return buf.toString(); + } + + /** + * Interface tag for {@link ASTLocusTag} provider. + */ + public static interface ASTLocusTagProvider { + /** + * Returns this instance's {@link ASTLocusTag}, if available, + * otherwise returns {@code null}. + */ + ASTLocusTag getASTLocusTag(); + } +} diff --git a/src/java/com/jogamp/gluegen/ConstantDefinition.java b/src/java/com/jogamp/gluegen/ConstantDefinition.java index 78d2e43..1ea4233 100644 --- a/src/java/com/jogamp/gluegen/ConstantDefinition.java +++ b/src/java/com/jogamp/gluegen/ConstantDefinition.java @@ -33,24 +33,27 @@ package com.jogamp.gluegen; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; import com.jogamp.gluegen.cgram.types.AliasedSymbol.AliasedSymbolImpl; import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol; import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp; /** Represents the definition of a constant which was provided either via a #define statement or through an enum definition. */ -public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSemanticSymbol { +public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSemanticSymbol, ASTLocusTagProvider { private final boolean relaxedEqSem; private final String sValue; private final long iValue; private final boolean hasIntValue; private final boolean isEnum; private final String enumName; + private final ASTLocusTag astLocus; /** Covering enums */ public ConstantDefinition(final String name, final long value, - final String enumName) { + final String enumName, + final ASTLocusTag astLocus) { super(name); this.relaxedEqSem = TypeConfig.relaxedEqualSemanticsTest(); this.sValue = String.valueOf(value); @@ -58,11 +61,13 @@ public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSema this.hasIntValue = true; this.isEnum = true; this.enumName = enumName; + this.astLocus = astLocus; } /** Covering defines */ public ConstantDefinition(final String name, - final String value) { + final String value, + final ASTLocusTag astLocus) { super(name); this.relaxedEqSem = TypeConfig.relaxedEqualSemanticsTest(); this.sValue = value; @@ -82,8 +87,12 @@ public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSema } this.isEnum = false; this.enumName = null; + this.astLocus = astLocus; } + @Override + public ASTLocusTag getASTLocusTag() { return astLocus; } + /** * Hash by its given {@link #getName() name}. */ diff --git a/src/java/com/jogamp/gluegen/GlueGen.java b/src/java/com/jogamp/gluegen/GlueGen.java index 6428469..1e879c7 100644 --- a/src/java/com/jogamp/gluegen/GlueGen.java +++ b/src/java/com/jogamp/gluegen/GlueGen.java @@ -208,12 +208,14 @@ public class GlueGen implements GlueEmitterControls { // iterate over all values in the enumeration for (int i = 0; i < enumeration.getNumEnumerates(); ++i) { final String enumElementName = enumeration.getEnumName(i); - allConstants.add(new ConstantDefinition(enumElementName, enumeration.getEnumValue(i), enumName)); + allConstants.add(new ConstantDefinition(enumElementName, enumeration.getEnumValue(i), + enumName, enumeration.getASTLocusTag())); } } for (final Object elem : lexer.getDefines()) { final Define def = (Define) elem; - allConstants.add(new ConstantDefinition(def.getName(), def.getValue())); + // TODO: Add ASTLocusTag + allConstants.add(new ConstantDefinition(def.getName(), def.getValue(), null)); } allFunctions = headerParser.getParsedFunctions(); diff --git a/src/java/com/jogamp/gluegen/GlueGenException.java b/src/java/com/jogamp/gluegen/GlueGenException.java new file mode 100644 index 0000000..3c52104 --- /dev/null +++ b/src/java/com/jogamp/gluegen/GlueGenException.java @@ -0,0 +1,95 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.gluegen; + +import com.jogamp.common.JogampRuntimeException; + +/** A generic exception for Jogamp errors used throughout the binding + as a substitute for {@link RuntimeException}. */ + +@SuppressWarnings("serial") +public class GlueGenException extends JogampRuntimeException { + final ASTLocusTag locus; + + public ASTLocusTag getASTLocusTag() { return locus; } + + /** Constructs a GlueGenException object. */ + public GlueGenException() { + super(); + locus = null; + } + + /** Constructs a GlueGenException object with the specified detail + message. */ + public GlueGenException(final String message) { + super(message); + locus = null; + } + + /** Constructs a GlueGenException object with the specified detail + message and root cause. */ + public GlueGenException(final String message, final Throwable cause) { + super(message, cause); + locus = null; + } + + /** Constructs a GlueGenException object with the specified root + cause. */ + public GlueGenException(final Throwable cause) { + super(cause); + locus = null; + } + + /** Constructs a GlueGenException object with the specified detail + message and root cause. */ + public GlueGenException(final String message, final ASTLocusTag locusTag) { + super(message); + this.locus = locusTag; + } + + /** Constructs a GlueGenException object with the specified detail + message and root cause. */ + public GlueGenException(final String message, final ASTLocusTag locusTag, final Throwable cause) { + super(message, cause); + this.locus = locusTag; + } + + public String toString() { + final StringBuffer buf = new StringBuffer(); + if (null != locus) { + buf.append(locus).append(": "); + } + buf.append(getLocalizedMessage()); + final String message = buf.toString(); + + final String className = getClass().getSimpleName(); + return null != message ? className + ": " + message : className; + } + +} diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java index 4db0482..17d51ab 100644 --- a/src/java/com/jogamp/gluegen/JavaEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaEmitter.java @@ -144,9 +144,14 @@ public class JavaEmitter implements GlueEmitter { // Duplicate alias .. check and add aliased name sym.rename(newName); // only rename to allow 'equalSemantics' to not care .. if( !dupSym.equalSemantics(sym) ) { - throw new RuntimeException( - String.format("Duplicate Name (alias) w/ incompatible value:%n have '%s',%n this '%s'", - dupSym.getAliasedString(), sym.getAliasedString())); + final String message = + String.format("Duplicate Name (alias) w/ incompatible value:%n have '%s',%n this '%s'", + dupSym.getAliasedString(), sym.getAliasedString()); + if( sym instanceof ASTLocusTagProvider ) { + throw new GlueGenException(message, ((ASTLocusTagProvider)sym).getASTLocusTag()); + } else { + throw new GlueGenException(message); + } } dupSym.addAliasedName(origName); } else { @@ -160,9 +165,14 @@ public class JavaEmitter implements GlueEmitter { if( null != dupSym ) { // Duplicate orig .. check and drop if( !dupSym.equalSemantics(sym) ) { - throw new RuntimeException( + final String message = String.format("Duplicate Name (orig) w/ incompatible value:%n have '%s',%n this '%s'", - dupSym.getAliasedString(), sym.getAliasedString())); + dupSym.getAliasedString(), sym.getAliasedString()); + if( sym instanceof ASTLocusTagProvider ) { + throw new GlueGenException(message, ((ASTLocusTagProvider)sym).getASTLocusTag()); + } else { + throw new GlueGenException(message); + } } } else { // No duplicate orig .. add diff --git a/src/java/com/jogamp/gluegen/cgram/TNode.java b/src/java/com/jogamp/gluegen/cgram/TNode.java index a564c54..70dc2c4 100644 --- a/src/java/com/jogamp/gluegen/cgram/TNode.java +++ b/src/java/com/jogamp/gluegen/cgram/TNode.java @@ -3,10 +3,14 @@ package com.jogamp.gluegen.cgram; import antlr.collections.AST; import antlr.CommonAST; import antlr.Token; + import java.lang.reflect.*; import java.util.Hashtable; import java.util.Enumeration; +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; + /** Class TNode is an implementation of the AST interface and adds many useful features: @@ -29,7 +33,8 @@ import java.util.Enumeration; */ -public class TNode extends CommonAST { +@SuppressWarnings("serial") +public class TNode extends CommonAST implements ASTLocusTagProvider { protected int ttype; protected String text; protected int lineNum = 0; @@ -40,7 +45,22 @@ public class TNode extends CommonAST { protected Hashtable attributes = null; static String tokenVocabulary; - + /** + * {@inheritDoc} + *

+ * If source is not available, + * implementation returns {@code null}. + *

+ */ + @Override + public ASTLocusTag getASTLocusTag() { + final Object s = getAttribute("source"); + if( null != s ) { + return new ASTLocusTag(s, getLineNum(), -1, getText()); + } else { + return null; + } + } /** Set the token vocabulary to a tokentypes class diff --git a/src/java/com/jogamp/gluegen/cgram/types/EnumType.java b/src/java/com/jogamp/gluegen/cgram/types/EnumType.java index f0e71dc..7fa22e4 100644 --- a/src/java/com/jogamp/gluegen/cgram/types/EnumType.java +++ b/src/java/com/jogamp/gluegen/cgram/types/EnumType.java @@ -42,12 +42,14 @@ package com.jogamp.gluegen.cgram.types; import java.util.ArrayList; import java.util.NoSuchElementException; +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp; /** Describes enumerated types. Enumerations are like ints except that they have a set of named values. */ -public class EnumType extends IntType implements Cloneable { +public class EnumType extends IntType implements Cloneable, ASTLocusTagProvider { private IntType underlyingType; @@ -101,22 +103,29 @@ public class EnumType extends IntType implements Cloneable { } private ArrayList enums; + private final ASTLocusTag astLocus; public EnumType(final String name) { super(name, SizeThunk.LONG, false, CVAttributes.CONST); this.underlyingType = new IntType(name, SizeThunk.LONG, false, CVAttributes.CONST); + this.astLocus = null; } - public EnumType(final String name, final SizeThunk enumSizeInBytes) { + public EnumType(final String name, final SizeThunk enumSizeInBytes, final ASTLocusTag astLocus) { super(name, enumSizeInBytes, false, CVAttributes.CONST); this.underlyingType = new IntType(name, enumSizeInBytes, false, CVAttributes.CONST); + this.astLocus = astLocus; } - protected EnumType(final String name, final IntType underlyingType, final int cvAttributes) { + protected EnumType(final String name, final IntType underlyingType, final int cvAttributes, final ASTLocusTag astLocus) { super(name, underlyingType.getSize(), underlyingType.isUnsigned(), cvAttributes); this.underlyingType = underlyingType; + this.astLocus = astLocus; } + @Override + public ASTLocusTag getASTLocusTag() { return astLocus; } + @Override public Object clone() { final EnumType n = (EnumType) super.clone(); @@ -244,7 +253,7 @@ public class EnumType extends IntType implements Cloneable { @Override Type newCVVariant(final int cvAttributes) { - final EnumType t = new EnumType(getName(), underlyingType, cvAttributes); + final EnumType t = new EnumType(getName(), underlyingType, cvAttributes, astLocus); t.enums = enums; return t; } diff --git a/src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java b/src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java index ee68b68..2b78e8c 100644 --- a/src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java +++ b/src/java/com/jogamp/gluegen/cgram/types/FunctionSymbol.java @@ -40,6 +40,8 @@ package com.jogamp.gluegen.cgram.types; import java.util.List; +import com.jogamp.gluegen.ASTLocusTag; +import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider; import com.jogamp.gluegen.cgram.types.AliasedSymbol.AliasedSymbolImpl; import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol; import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp; @@ -57,15 +59,26 @@ import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp; * Deep comparison can be performed via {@link #isCompletelyEqual(Object o)}; *

**/ -public class FunctionSymbol extends AliasedSymbolImpl implements AliasedSemanticSymbol { +public class FunctionSymbol extends AliasedSymbolImpl implements AliasedSemanticSymbol, ASTLocusTagProvider { private final FunctionType type; + private final ASTLocusTag astLocus; public FunctionSymbol(final String name, final FunctionType type) { super(name); this.type = type; + this.astLocus = null; } + public FunctionSymbol(final String name, final FunctionType type, final ASTLocusTag locus) { + super(name); + this.type = type; + this.astLocus = locus; + } + + @Override + public ASTLocusTag getASTLocusTag() { return astLocus; } + /** Returns the type of this function. Do not add arguments to it directly; use addArgument instead. */ public FunctionType getType() { -- cgit v1.2.3