tracesrv/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/rules/AutoAddFunctionParametersRule.java
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
56
hgs
parents:
diff changeset
     1
/*
hgs
parents:
diff changeset
     2
* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
hgs
parents:
diff changeset
     3
* All rights reserved.
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     8
*
hgs
parents:
diff changeset
     9
* Initial Contributors:
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    11
*
hgs
parents:
diff changeset
    12
* Contributors:
hgs
parents:
diff changeset
    13
*
hgs
parents:
diff changeset
    14
* Description:
hgs
parents:
diff changeset
    15
*
hgs
parents:
diff changeset
    16
* Trace rule for automatically adding function parameters to a trace
hgs
parents:
diff changeset
    17
*
hgs
parents:
diff changeset
    18
*/
hgs
parents:
diff changeset
    19
package com.nokia.tracecompiler.engine.rules;
hgs
parents:
diff changeset
    20
hgs
parents:
diff changeset
    21
import java.util.ArrayList;
hgs
parents:
diff changeset
    22
hgs
parents:
diff changeset
    23
import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorMessages;
hgs
parents:
diff changeset
    24
import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals;
hgs
parents:
diff changeset
    25
import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.StringErrorParameters;
hgs
parents:
diff changeset
    26
import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode;
hgs
parents:
diff changeset
    27
import com.nokia.tracecompiler.engine.header.ComplexHeaderRule;
hgs
parents:
diff changeset
    28
import com.nokia.tracecompiler.engine.source.TraceParameterFormattingRule;
hgs
parents:
diff changeset
    29
import com.nokia.tracecompiler.model.Trace;
hgs
parents:
diff changeset
    30
import com.nokia.tracecompiler.model.TraceCompilerException;
hgs
parents:
diff changeset
    31
import com.nokia.tracecompiler.model.TraceConstantTable;
hgs
parents:
diff changeset
    32
import com.nokia.tracecompiler.model.TraceObjectRuleCreateObject;
hgs
parents:
diff changeset
    33
import com.nokia.tracecompiler.model.TraceObjectRuleRemoveOnCreate;
hgs
parents:
diff changeset
    34
import com.nokia.tracecompiler.model.TraceParameter;
hgs
parents:
diff changeset
    35
import com.nokia.tracecompiler.source.SourceConstants;
hgs
parents:
diff changeset
    36
import com.nokia.tracecompiler.source.SourceContext;
hgs
parents:
diff changeset
    37
import com.nokia.tracecompiler.source.SourceParameter;
hgs
parents:
diff changeset
    38
import com.nokia.tracecompiler.source.SourceParserException;
hgs
parents:
diff changeset
    39
import com.nokia.tracecompiler.source.SourceUtils;
hgs
parents:
diff changeset
    40
import com.nokia.tracecompiler.source.TypeMapping;
hgs
parents:
diff changeset
    41
hgs
parents:
diff changeset
    42
/**
hgs
parents:
diff changeset
    43
 * Trace rule for automatically adding function parameters to a trace
hgs
parents:
diff changeset
    44
 * 
hgs
parents:
diff changeset
    45
 */
hgs
parents:
diff changeset
    46
public final class AutoAddFunctionParametersRule extends RuleBase implements
hgs
parents:
diff changeset
    47
		TraceObjectRuleCreateObject, TraceObjectRuleRemoveOnCreate {
hgs
parents:
diff changeset
    48
hgs
parents:
diff changeset
    49
	/**
hgs
parents:
diff changeset
    50
	 * Warning about value-to-pointer conversion
hgs
parents:
diff changeset
    51
	 */
hgs
parents:
diff changeset
    52
	private static final String VALUE_TO_POINTER_WARNING = Messages
hgs
parents:
diff changeset
    53
			.getString("AutoAddFunctionParametersRule.UnrecognizedTypeWarning"); //$NON-NLS-1$
hgs
parents:
diff changeset
    54
hgs
parents:
diff changeset
    55
	/*
hgs
parents:
diff changeset
    56
	 * (non-Javadoc)
hgs
parents:
diff changeset
    57
	 * 
hgs
parents:
diff changeset
    58
	 * @see
hgs
parents:
diff changeset
    59
	 * com.nokia.tracecompiler.model.TraceObjectRuleCreateObject#createObject()
hgs
parents:
diff changeset
    60
	 */
hgs
parents:
diff changeset
    61
	public void createObject() throws TraceCompilerException {
hgs
parents:
diff changeset
    62
		SourceContext context = TraceCompilerEngineGlobals.getSourceContextManager()
hgs
parents:
diff changeset
    63
				.getContext();
hgs
parents:
diff changeset
    64
		Trace trace = (Trace) getOwner();
hgs
parents:
diff changeset
    65
		if (context != null) {
hgs
parents:
diff changeset
    66
			boolean valid = false;
hgs
parents:
diff changeset
    67
			ArrayList<SourceParameter> list = tokenizeParameters(context);
hgs
parents:
diff changeset
    68
hgs
parents:
diff changeset
    69
			trace.getModel().startProcessing();
hgs
parents:
diff changeset
    70
			try {
hgs
parents:
diff changeset
    71
				createParameters(trace, list);
hgs
parents:
diff changeset
    72
			} finally {
hgs
parents:
diff changeset
    73
				trace.getModel().processingComplete();
hgs
parents:
diff changeset
    74
			}
hgs
parents:
diff changeset
    75
			// At least one parameter must be parsed from source except for function entry extension
hgs
parents:
diff changeset
    76
			valid = trace.getParameterCount() > 0 || trace.getExtension(EntryTraceRule.class) != null;
hgs
parents:
diff changeset
    77
hgs
parents:
diff changeset
    78
			if (!valid) {
hgs
parents:
diff changeset
    79
				String msg = TraceCompilerEngineErrorMessages.getErrorMessage(
hgs
parents:
diff changeset
    80
						TraceCompilerErrorCode.CANNOT_PARSE_FUNCTION_PARAMETERS,
hgs
parents:
diff changeset
    81
						null);
hgs
parents:
diff changeset
    82
				TraceCompilerEngineGlobals.getEvents().postWarningMessage(msg, trace);
hgs
parents:
diff changeset
    83
				// Removes the complex rule -> Function is not generated and
hgs
parents:
diff changeset
    84
				// source does not compile
hgs
parents:
diff changeset
    85
				trace.removeExtensions(ComplexHeaderRule.class);
hgs
parents:
diff changeset
    86
			}
hgs
parents:
diff changeset
    87
		} else {
hgs
parents:
diff changeset
    88
			String msg = TraceCompilerEngineErrorMessages.getErrorMessage(
hgs
parents:
diff changeset
    89
					TraceCompilerErrorCode.NO_CONTEXT_FOR_LOCATION, null);
hgs
parents:
diff changeset
    90
			TraceCompilerEngineGlobals.getEvents().postErrorMessage(msg, null, true);
hgs
parents:
diff changeset
    91
			// Removes the complex rule -> Function is not generated and
hgs
parents:
diff changeset
    92
			// source does not compile
hgs
parents:
diff changeset
    93
			trace.removeExtensions(ComplexHeaderRule.class);
hgs
parents:
diff changeset
    94
		}
hgs
parents:
diff changeset
    95
	}
hgs
parents:
diff changeset
    96
hgs
parents:
diff changeset
    97
	/**
hgs
parents:
diff changeset
    98
	 * Creates the parameters to the trace
hgs
parents:
diff changeset
    99
	 * 
hgs
parents:
diff changeset
   100
	 * @param owner
hgs
parents:
diff changeset
   101
	 *            the trace
hgs
parents:
diff changeset
   102
	 * @param list
hgs
parents:
diff changeset
   103
	 *            the parameter list parsed from source
hgs
parents:
diff changeset
   104
	 * @throws TraceCompilerException 
hgs
parents:
diff changeset
   105
	 */
hgs
parents:
diff changeset
   106
	private void createParameters(Trace owner, ArrayList<SourceParameter> list) throws TraceCompilerException {
hgs
parents:
diff changeset
   107
hgs
parents:
diff changeset
   108
		// If any of the parameters is "...", clear the whole parameter list
hgs
parents:
diff changeset
   109
		for (SourceParameter param : list) {
hgs
parents:
diff changeset
   110
			String type = param.getType();
hgs
parents:
diff changeset
   111
			if (type != null
hgs
parents:
diff changeset
   112
					&& type.equals(SourceConstants.VARIABLE_ARG_LIST_INDICATOR)) {
hgs
parents:
diff changeset
   113
				list.clear();
hgs
parents:
diff changeset
   114
				
hgs
parents:
diff changeset
   115
				
hgs
parents:
diff changeset
   116
				String msg = TraceCompilerEngineErrorMessages.getErrorMessage(
hgs
parents:
diff changeset
   117
						TraceCompilerErrorCode.VAR_ARG_LIST_PARAMETER_FOUND,
hgs
parents:
diff changeset
   118
						null);
hgs
parents:
diff changeset
   119
				TraceCompilerEngineGlobals.getEvents().postWarningMessage(msg, owner);
hgs
parents:
diff changeset
   120
				break;
hgs
parents:
diff changeset
   121
			}
hgs
parents:
diff changeset
   122
		}
hgs
parents:
diff changeset
   123
hgs
parents:
diff changeset
   124
		StringBuilder str = new StringBuilder();
hgs
parents:
diff changeset
   125
		for (SourceParameter param : list) {
hgs
parents:
diff changeset
   126
			TraceParameter parameter = createParameter(owner, param);
hgs
parents:
diff changeset
   127
			if (parameter != null) {
hgs
parents:
diff changeset
   128
				str.append(SourceConstants.PARAMETER_SEPARATOR);
hgs
parents:
diff changeset
   129
				TraceParameterFormattingRule rule = parameter
hgs
parents:
diff changeset
   130
						.getExtension(TraceParameterFormattingRule.class);
hgs
parents:
diff changeset
   131
				if (rule != null) {
hgs
parents:
diff changeset
   132
					str.append(rule.mapNameToSource(param.getName()));
hgs
parents:
diff changeset
   133
				} else {
hgs
parents:
diff changeset
   134
					str.append(param.getName());
hgs
parents:
diff changeset
   135
				}
hgs
parents:
diff changeset
   136
			}
hgs
parents:
diff changeset
   137
			// The location will be referenced by event handlers if
hgs
parents:
diff changeset
   138
			// they need it. Otherwise it will be removed from the
hgs
parents:
diff changeset
   139
			// source
hgs
parents:
diff changeset
   140
			param.getSourceLocation().dereference();
hgs
parents:
diff changeset
   141
		}
hgs
parents:
diff changeset
   142
		// The header extension is stored in case of complex function entry
hgs
parents:
diff changeset
   143
		// trace
hgs
parents:
diff changeset
   144
		EntryTraceRule entryRule = owner.getExtension(EntryTraceRule.class);
hgs
parents:
diff changeset
   145
		ComplexHeaderRuleImpl complex = owner
hgs
parents:
diff changeset
   146
				.getExtension(ComplexHeaderRuleImpl.class);
hgs
parents:
diff changeset
   147
		if (entryRule != null && complex != null) {
hgs
parents:
diff changeset
   148
			complex.setTraceIDDefineExtension(str.toString());
hgs
parents:
diff changeset
   149
		}
hgs
parents:
diff changeset
   150
	}
hgs
parents:
diff changeset
   151
hgs
parents:
diff changeset
   152
	/**
hgs
parents:
diff changeset
   153
	 * Processes the parameters of given source context
hgs
parents:
diff changeset
   154
	 * 
hgs
parents:
diff changeset
   155
	 * @param context
hgs
parents:
diff changeset
   156
	 *            the context
hgs
parents:
diff changeset
   157
	 * @return list of parameters
hgs
parents:
diff changeset
   158
	 * @throws TraceCompilerException 
hgs
parents:
diff changeset
   159
	 */
hgs
parents:
diff changeset
   160
	private ArrayList<SourceParameter> tokenizeParameters(SourceContext context) throws TraceCompilerException {
hgs
parents:
diff changeset
   161
		ArrayList<SourceParameter> list = new ArrayList<SourceParameter>();
hgs
parents:
diff changeset
   162
		try {
hgs
parents:
diff changeset
   163
			context.parseParameters(list);
hgs
parents:
diff changeset
   164
		} catch (SourceParserException e) {
hgs
parents:
diff changeset
   165
			TraceCompilerException exception = new TraceCompilerException(
hgs
parents:
diff changeset
   166
					TraceCompilerErrorCode.UNEXPECTED_EXCEPTION, e);
hgs
parents:
diff changeset
   167
			TraceCompilerEngineGlobals.getEvents().postError(
hgs
parents:
diff changeset
   168
					exception);
hgs
parents:
diff changeset
   169
			list = null;
hgs
parents:
diff changeset
   170
		}
hgs
parents:
diff changeset
   171
		return list;
hgs
parents:
diff changeset
   172
	}
hgs
parents:
diff changeset
   173
hgs
parents:
diff changeset
   174
	/**
hgs
parents:
diff changeset
   175
	 * Creates a TraceParameter based on parameter parsed from source
hgs
parents:
diff changeset
   176
	 * 
hgs
parents:
diff changeset
   177
	 * @param owner
hgs
parents:
diff changeset
   178
	 *            the owning trace object
hgs
parents:
diff changeset
   179
	 * @param param
hgs
parents:
diff changeset
   180
	 *            the parameter found from source
hgs
parents:
diff changeset
   181
	 * @return the parameter
hgs
parents:
diff changeset
   182
	 */
hgs
parents:
diff changeset
   183
	private TraceParameter createParameter(Trace owner, SourceParameter param) {
hgs
parents:
diff changeset
   184
		TraceConstantTable foundTable = RuleUtils.findConstantTableByType(owner
hgs
parents:
diff changeset
   185
				.getModel(), param);
hgs
parents:
diff changeset
   186
		TraceParameter parameter = null;
hgs
parents:
diff changeset
   187
		if (foundTable == null) {
hgs
parents:
diff changeset
   188
			TypeMapping type = SourceUtils.mapSymbianTypeToParameterType(param);
hgs
parents:
diff changeset
   189
			if (type != null) {
hgs
parents:
diff changeset
   190
				if (!type.isVoid()) {
hgs
parents:
diff changeset
   191
					parameter = createParameter(owner, param, type);
hgs
parents:
diff changeset
   192
				}
hgs
parents:
diff changeset
   193
			} else {
hgs
parents:
diff changeset
   194
				StringErrorParameters params = new StringErrorParameters();
hgs
parents:
diff changeset
   195
				params.string = param.getType();
hgs
parents:
diff changeset
   196
				TraceCompilerException exception = new TraceCompilerException(
hgs
parents:
diff changeset
   197
						TraceCompilerErrorCode.INVALID_PARAMETER_TYPE,
hgs
parents:
diff changeset
   198
						params, param.getSourceLocation());
hgs
parents:
diff changeset
   199
				TraceCompilerEngineGlobals.getEvents().postError(
hgs
parents:
diff changeset
   200
						exception);
hgs
parents:
diff changeset
   201
			}
hgs
parents:
diff changeset
   202
		} else {
hgs
parents:
diff changeset
   203
			parameter = createParameter(owner, param, foundTable);
hgs
parents:
diff changeset
   204
		}
hgs
parents:
diff changeset
   205
		return parameter;
hgs
parents:
diff changeset
   206
	}
hgs
parents:
diff changeset
   207
hgs
parents:
diff changeset
   208
	/**
hgs
parents:
diff changeset
   209
	 * Processes a non-void parameter type that was not associated with a
hgs
parents:
diff changeset
   210
	 * constant table
hgs
parents:
diff changeset
   211
	 * 
hgs
parents:
diff changeset
   212
	 * @param owner
hgs
parents:
diff changeset
   213
	 *            the owner for the parameter
hgs
parents:
diff changeset
   214
	 * @param param
hgs
parents:
diff changeset
   215
	 *            the parameter found from source
hgs
parents:
diff changeset
   216
	 * @param type
hgs
parents:
diff changeset
   217
	 *            the parameter type as parsed by source package
hgs
parents:
diff changeset
   218
	 * @return the parameter
hgs
parents:
diff changeset
   219
	 */
hgs
parents:
diff changeset
   220
	private TraceParameter createParameter(Trace owner, SourceParameter param,
hgs
parents:
diff changeset
   221
			TypeMapping type) {
hgs
parents:
diff changeset
   222
		String name = param.getName();
hgs
parents:
diff changeset
   223
		TraceParameter retval = null;
hgs
parents:
diff changeset
   224
		if (name == null || name.length() == 0) {
hgs
parents:
diff changeset
   225
			String s = TraceCompilerEngineErrorMessages.getErrorMessage(
hgs
parents:
diff changeset
   226
					TraceCompilerErrorCode.EMPTY_PARAMETER_NAME, null);
hgs
parents:
diff changeset
   227
			TraceCompilerEngineGlobals.getEvents().postWarningMessage(s,
hgs
parents:
diff changeset
   228
					param.getSourceLocation());
hgs
parents:
diff changeset
   229
		} else {
hgs
parents:
diff changeset
   230
			try {
hgs
parents:
diff changeset
   231
				retval = RuleUtils.createParameterFromType(owner, name, type);
hgs
parents:
diff changeset
   232
				if (retval != null && type.valueToPointer) {
hgs
parents:
diff changeset
   233
					// Posts a warning about value-to-pointer conversion
hgs
parents:
diff changeset
   234
					TraceCompilerEngineGlobals.getEvents()
hgs
parents:
diff changeset
   235
							.postWarningMessage(VALUE_TO_POINTER_WARNING,
hgs
parents:
diff changeset
   236
									param.getSourceLocation());
hgs
parents:
diff changeset
   237
				}
hgs
parents:
diff changeset
   238
			} catch (TraceCompilerException e) {
hgs
parents:
diff changeset
   239
				// Changes the source of the error to the location that failed
hgs
parents:
diff changeset
   240
				TraceCompilerException exception = new TraceCompilerException(e.getErrorCode(), e
hgs
parents:
diff changeset
   241
						.getErrorParameters(), param
hgs
parents:
diff changeset
   242
						.getSourceLocation());
hgs
parents:
diff changeset
   243
				TraceCompilerEngineGlobals.getEvents().postError(
hgs
parents:
diff changeset
   244
						exception);
hgs
parents:
diff changeset
   245
			}
hgs
parents:
diff changeset
   246
		}
hgs
parents:
diff changeset
   247
		return retval;
hgs
parents:
diff changeset
   248
	}
hgs
parents:
diff changeset
   249
hgs
parents:
diff changeset
   250
	/**
hgs
parents:
diff changeset
   251
	 * Processes a non-void parameter type that was associated with a constant
hgs
parents:
diff changeset
   252
	 * table
hgs
parents:
diff changeset
   253
	 * 
hgs
parents:
diff changeset
   254
	 * @param owner
hgs
parents:
diff changeset
   255
	 *            the owner for the parameter
hgs
parents:
diff changeset
   256
	 * @param param
hgs
parents:
diff changeset
   257
	 *            the parameter found from source
hgs
parents:
diff changeset
   258
	 * @param table
hgs
parents:
diff changeset
   259
	 *            the constant table the parameter was associated to
hgs
parents:
diff changeset
   260
	 * @return the parameter
hgs
parents:
diff changeset
   261
	 */
hgs
parents:
diff changeset
   262
	private TraceParameter createParameter(Trace owner, SourceParameter param,
hgs
parents:
diff changeset
   263
			TraceConstantTable table) {
hgs
parents:
diff changeset
   264
		String name = param.getName();
hgs
parents:
diff changeset
   265
		TraceParameter retval = null;
hgs
parents:
diff changeset
   266
		if (name == null || name.length() == 0) {
hgs
parents:
diff changeset
   267
			String s = TraceCompilerEngineErrorMessages.getErrorMessage(
hgs
parents:
diff changeset
   268
					TraceCompilerErrorCode.EMPTY_PARAMETER_NAME, null);
hgs
parents:
diff changeset
   269
			TraceCompilerEngineGlobals.getEvents().postWarningMessage(s,
hgs
parents:
diff changeset
   270
					param.getSourceLocation());
hgs
parents:
diff changeset
   271
		} else {
hgs
parents:
diff changeset
   272
			try {
hgs
parents:
diff changeset
   273
				retval = RuleUtils.createParameterFromConstantTable(owner,
hgs
parents:
diff changeset
   274
						name, table);
hgs
parents:
diff changeset
   275
			} catch (TraceCompilerException e) {
hgs
parents:
diff changeset
   276
				// Changes the source of the error to the location that failed
hgs
parents:
diff changeset
   277
				TraceCompilerException exception = new TraceCompilerException(e.getErrorCode(), e
hgs
parents:
diff changeset
   278
						.getErrorParameters(), param
hgs
parents:
diff changeset
   279
						.getSourceLocation());
hgs
parents:
diff changeset
   280
				TraceCompilerEngineGlobals.getEvents().postError(
hgs
parents:
diff changeset
   281
						exception);
hgs
parents:
diff changeset
   282
			}
hgs
parents:
diff changeset
   283
		}
hgs
parents:
diff changeset
   284
		return retval;
hgs
parents:
diff changeset
   285
	}
hgs
parents:
diff changeset
   286
hgs
parents:
diff changeset
   287
	/*
hgs
parents:
diff changeset
   288
	 * (non-Javadoc)
hgs
parents:
diff changeset
   289
	 * 
hgs
parents:
diff changeset
   290
	 * @see
hgs
parents:
diff changeset
   291
	 * com.nokia.tracecompiler.model.TraceObjectRuleRemoveOnCreate#canBeRemoved()
hgs
parents:
diff changeset
   292
	 */
hgs
parents:
diff changeset
   293
	public boolean canBeRemoved() {
hgs
parents:
diff changeset
   294
		// This is not copied to exit trace -> Can be removed
hgs
parents:
diff changeset
   295
		return true;
hgs
parents:
diff changeset
   296
	}
hgs
parents:
diff changeset
   297
hgs
parents:
diff changeset
   298
}